總結一下storybook增加實時交互代碼修改顯示結果,自動生成API的Demo頁的操作。(React+TypeScript架構)
對比圖:
vs
第一步,由於我先前使用的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.js和index.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,所以不加的話這些都可以省略。