配置

自定义配置

Storybook针对不同的开发场景提供了非常灵活的配置方案。

自定义Webpack

Storybook允许我们通过自定义Webpack配置文件来修改Webpack的打包流程。我们可以创建 .storybook/webpack.config.js 配置文件,然后进行Webpack调试,首先在文件中添加如下内容:

module.exports = async ({ config }) =>
  console.dir(config.plugins, { depth: null }) || config;

然后运行 $ yarn storybook --debug-webpack。当配置文件导出的是函数时,Storybook会自动调用该函数,然后根据该函数的结果来修正Webpack的配置。譬如,我们要增加对SCSS的支持:

const path = require("path");

// Export a function. Accept the base config as the only param.
module.exports = async ({ config, mode }) => {
  // `mode` has a value of 'DEVELOPMENT' or 'PRODUCTION'
  // You can change the configuration based on that.
  // 'PRODUCTION' is used when building the static version of storybook.

  // Make whatever fine-grained changes you need
  config.module.rules.push({
    test: /\.scss$/,
    use: ["style-loader", "css-loader", "sass-loader"],
    include: path.resolve(__dirname, "../")
  });

  // Return the altered config
  return config;
};

值得说明的是,这里的Webpack自定义配置仅会影响到用户自身的组件渲染,而Storybook框架本身的渲染还是会根据自己的Webpack配置来。

自定义TypeScript支持

笔者的Web项目主要是以TypeScript进行开发,首先需要添加 awesome-typescript-loader

$ yarn add -D typescript
$ yarn add -D awesome-typescript-loader
$ yarn add -D @types/storybook__react # typings
$ yarn add -D @storybook/addon-info react-docgen-typescript-loader # optional but recommended
$ yarn add -D jest "@types/jest" ts-jest #testing

然后在自定义的Webpack配置中添加如下的配置:

module.exports = ({ config }) => {
  config.module.rules.push({
    test: /\.(ts|tsx)$/,
    use: [
      {
        loader: require.resolve("awesome-typescript-loader")
      },
      // Optional
      {
        loader: require.resolve("react-docgen-typescript-loader")
      }
    ]
  });
  config.resolve.extensions.push(".ts", ".tsx");
  return config;
};

参考的tsconfig.json配置如下:

{
  "compilerOptions": {
    "outDir": "build/lib",
    "module": "commonjs",
    "target": "es5",
    "lib": ["es5", "es6", "es7", "es2017", "dom"],
    "sourceMap": true,
    "allowJs": false,
    "jsx": "react",
    "moduleResolution": "node",
    "rootDirs": ["src", "stories"],
    "baseUrl": "src",
    "forceConsistentCasingInFileNames": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "suppressImplicitAnyIndexErrors": true,
    "noUnusedLocals": true,
    "declaration": true,
    "allowSyntheticDefaultImports": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  },
  "include": ["src/**/*", "stories/**/*"],
  "exclude": ["node_modules", "build", "scripts"]
}

然后在config.ts文件中引入全部的Stories:

import { configure } from "@storybook/react";
// automatically import all files ending in *.stories.tsx
const req = require.context("../stories", true, /\.stories\.tsx$/);

function loadStories() {
  req.keys().forEach(req);
}

configure(loadStories, module);

我们还可以利用TSDocgen扩展来自动地生成配套说明文档:

import * as React from "react";
import { storiesOf } from "@storybook/react";
import { action } from "@storybook/addon-actions";
import TicTacToeCell from "./TicTacToeCell";

const stories = storiesOf("Components", module);

stories.add(
  "TicTacToeCell",
  () => (
    <TicTacToeCell
      value="X"
      position={{ x: 0, y: 0 }}
      onClick={action("onClick")}
    />
  ),
  { info: { inline: true } }
);
上一页
下一页