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,所以不加的话这些都可以省略。

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