storybook增加實時交互代碼修改顯示結果(React+TypeScript)

總結一下storybook增加實時交互代碼修改顯示結果,自動生成API的Demo頁的操作。(React+TypeScript架構)

對比圖:原storybook

vs

現storybook

第一步,由於我先前使用的storybook是3.4.1,而參考的例子:https://wix-style-react.now.sh/ 是5.3.19,差了兩個大版本,爲了避免麻煩我先把已用到的相關插件一塊升級,涉及:@types/storybook__addon-actions、@types/storybook__react、file-loader、ts-loader

然後代碼原封不動的跑先前的代碼沒想到也能跑得通,看來storybook的兼容性做得挺好。

 

第二步就是storybook的邏輯改造了,主要引入了wix-storybook-utils、yoshi、yoshi-config、yoshi-style-dependencies。我將例子中的代碼搬過來後並不會自動跑它的story。對比後發現:

1、storybook的config.js裏我的是require('glob-loader!./stories.pattern'),示例的是require('../stories')

2、我的文件名story.tsx + 內部import { storiesOf } from '@storybook/react'自動就能被識別,而示例中的story.js只是單純export default一個對象,再通過stories\index.js文件中的require('../src/xxx/docs/index.story')啓動;

3、storybook的webpack.config.js裏,示例主要通過

      {
        test: /\.story\.js$/,
        loader: 'wix-storybook-utils/loader',
        options: {
          storyConfig: {
            moduleName: 'wix-style-react',
            importFormat: "import { %componentName } from '%moduleName'",
          },
        },
      }

這一塊,把它的樣式給跑起來的。

 

第三步代碼改造,我需要在儘量不修改原代碼的基礎上,增加doc文件夾下examples.jsindex.story.js兩個文件,重點說說後者,因爲和原來的寫法完全不一樣了:

我把示例的 import allComponents from '../../../stories/utils/allComponents' 改成了 import * as allComponents from '../../../index',直接從輸出口調,示例裏是走stories加了倆我用不到的組件再轉到index,繞了個大彎。後來發現如果要用到外用組件,其實在這彎裏寫也不錯。我是單獨Import需要的第三方組件,再把它這樣處理了const code = config => baseCode({ components: {...allComponents, Checkbox}, ...config });

 

第四步也是困擾了我近一天的css引入問題,之前webpack能跑起來,但不能引用新版storybook,而新的webpack兩邊storybook都能跑起來,但是CSS必需引成一個對象,再通過對象.class交給className。如果樣式全改成這樣引入,那修改的代碼量太多了……

於是我試了各種辦法:

不行的方法之一,將原webpack的rules加到裏面,它會報錯說 Rule can only have one result source (provided use and loaders):

{
  test: /\.scss$/,
  loaders: ["style-loader", "css-loader", "sass-loader"],
  include: path.resolve(__dirname, "../")
}

不行的方法之二,在module.exports = ({ config }) => 的處理開頭增加push,但是沒有任何作用(如果改成第一種形式引入,又會報一樣的錯):

        config.module.rules.push(
            {
                test: /\.scss$/,
                loader: "sass-resources-loader"
            }
        );

不行的方法之三,我把module.exports的return打印出來,發現了它其實自帶css/scss之類的處理,所以將它引用成一個對象的形式能正常使用,但我現在就只想引用成全局的……於是我將它的rules進行各種篡改,uses、loaders、options、oneof全都試了個遍……反正就是二者不兼容,要麼沒用要麼報錯。

妥協的處理方法

經過無數次試驗我突然想到,既然css/scss都被你霸佔了,那我乾脆自創個擴展名tcss,然後加在rules的最後:

      {
        test: /\.tcss$/,
        use: [{ loader: 'style-loader' }, { loader: 'css-loader' }, { loader: 'sass-loader' }]
      }

只要一個story引用了這個index.tcss就可以實現全局化css的功能了,而這文件裏的內容也很簡單,將原本我要的引起來,又不會影響整個組件的打包,還不需要輸出,單純就是給story用就夠了:

@import 'index.scss';

@import '../node_modules/simplebar/dist/simplebar.min.css';

@import '../node_modules/@blueprintjs/core/lib/css/blueprint.css';

 

另外,爲了使Playground能用:

1、原組件的Test.tsx只在export後面加了個default

2、原index.ts改成index.js,內容由export { Test } from './Test'變成export { default } from './Test.tsx';

3、增加index.d.ts,內容只要寫import React from 'react';export default class Realtime{}

……說實話,有點得不償失的感覺,因爲Description標籤頁變相就是個Playground,所以不加的話這些都可以省略。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章