---
sidebar_position: 5
---

# 使用 Storybook

[Storybook](https://storybook.js.org/) 是一个专门用于组件调试的工具，它围绕着组件开发提供了：

- 丰富多样的调试能力
- 可与一些测试工具结合使用
- 可重复使用的文档内容
- 可分享能力
- 工作流程自动化

在使用 Storybook 时，难免会遇到各种配置问题，需要手动配置 Babel 插件，手动配置 Webpack 去支持 less，sass 等。
Modern.js 集成了 Storybook，这对于我们开发 Storybook 项目来说极大地简化了配置工作。

## V7 (推荐)

### 开启 Storybook

可以直接使用如下命令开启 Storybook 功能。

```bash
$ npx modern new
? 请选择你想要的操作 启用可选功能
? 请选择功能名称 启用「Storybook」V7
```

该命令会创建好 Storybook 常用的模版，包括

- 创建配置文件夹 `.storybook`，以及默认配置文件 `.storybook/main.ts`
- 创建 stories 组件示例
- 更新 package.json，新增依赖 @storybook/addon-essential 和 @modern-js/storybook，以及创建 storybook 相关脚本。

### 开启产物调试

事实上，Modern.js Module 是基于 esbuild 实现的，而 Storybook 使用 Webpack 作为默认构建工具，二者的配置无法完全兼容，
所以这里我们推荐先对组件进行构建，然后在 stories 里引入组件产物。

引入组件产物的方式非常简单，假设你的模块导出了一个 Button 组件，那么在 stories 里可以这样使用:

```ts filename="stories/index.stories.tsx"
import { Button } from '.';

export const YourStory = () => <Button />;

export default {
  title: 'Your Stories',
};
```

如果想要更新组件，则可以在启动 Storybook 前启动监听模式的构建：

```bash
modern build --watch
```

:::info
在开发过程中，可能会遇到无法实时获得类型定义的情况。因为只有当保存代码后，产物目录下的类型文件才会更新。此时：

对于 `pnpm` 的项目，可以按照下面的内容对 `package.json` 进行修改：

```ts
{
    "name": "foo",
    "main": "./dist/index.js",
    "types": "./src/index.ts",
    "publishConfig": {
      "types": "./dist/index.d.ts",
    }
}
```

> 关于 pnpm 的 `publishConfig` 的使用，可以阅读下面这个[链接](https://pnpm.io/package_json#publishconfig)。

而对于 npm 和 Yarn 的项目，则只能通过手动的方式在**开发阶段**和**发布阶段**对 `package.json` 的 `types` 的值进行修改。
:::

### 开启 Rspack 构建

Rspack 构建速度非常快，只需要如下配置即可使用 Rspack 作为构建工具。

```diff filename='.storybook/main.js'
const config = {
  framework: {
    name: '@modern-js/storybook',
    options: {
-      bundler: 'webpack'
+      bundler: 'rspack'
    },
  },
  typescript: {
-    reactDocgen: 'react-docgen-typescript'
+    reactDocgen: 'react-docgen'
  }
};

export default config;
```

注意上面配置中，更改了 reactDocgen 配置，因为 Rspack 目前还不支持 @storybook/react-docgen-typescript-plugin。

### 配置

在 `.storybook/main.js` 中包含一些独有的配置。

#### bundler

- **类型**: `'webpack' | 'rspack'`
- **默认值**: `webpack`

指定底层打包工具使用 Webpack 还是 Rspack。

```javascript filename='.storybook/main.js'
const config = {
  framework: {
    name: '@modern-js/storybook',
    options: {
      bundler: 'rspack',
    },
  },
};

export default config;
```

#### builderConfig

- **类型**: `BuilderConfig`
- **默认值**: `undefined`

Modern.js 的 Storybook 构建能力由 [Rsbuild](https://rsbuild.rs/) 提供，可通过 builderConfig 修改 Rsbuild 构建配置。

```javascript filename='.storybook/main.js'
const config = {
  framework: {
    name: '@modern-js/storybook',
    options: {
      builderConfig: {
        alias: {
          react: require.resolve('react'),
          'react-dom': require.resolve('react-dom'),
        },
      },
    },
  },
};

export default config;
```

### 命令行

@modern-js/storybook 代理了部分 storybook cli 的命令。

#### storybook dev

启动 Storybook，查看[详情](https://storybook.js.org/docs/react/api/cli-options#dev)

#### storybook build

对 Storybook 进行生产环境构建，查看[详情](https://storybook.js.org/docs/react/api/cli-options#build)

### 配置文件

配置文件中除了 Rsbuild 配置还包含一个额外的字段，builderPlugins，方便使用 Rsbuild 插件，例如启用 SWC 编译。

```typescript filename='modern.config.ts'
import { defineConfig } from '@modern-js/storybook';
import { pluginSwc } from '@rsbuild/plugin-webpack-swc';

const config = defineConfig({
  builderPlugins: [pluginSwc()],
});

export default config;
```

## 从 V6 迁移至 V7

我们对于两个版本的支持方式不同，因此如果你是从 V6 迁移至 V7 的用户，我们希望你也按上述方式使用 V7，同时做以下调整:

- 配置文件：将原来 `root/config/storybook/main.(j|t)s` 里的自定义配置（如果有）迁移到新的 `root/.storybook/main.(j|t)s`。
- 依赖：升级 `@storybook/addon-*` 系列依赖（如果有）到 7 版本，并删除 `@modern-js/plugin-storybook` 依赖。
- 命令: 将原来 `edenx dev storybook` 和 `edenx build --platform` 命令删除，如果习惯了原来的 `pnpm run dev` 的调用方式，可以
  将其替换成 `storybook dev -p 6006` 和 `storybook build`。
- modern.config.(j|t)s : 删除 `@modern-js/plugin-storybook` 插件的注册。

## V6 (legacy)

从 `MAJOR_VERSION.40.0` 版本开始，`@modern-js/plugin-storybook`将停止迭代。建议使用 V7 版本。
如果你的 `@modern-js/module-tools` 版本低于 `MAJOR_VERSION.40.0`，可以按照以下方式使用 Storybook V6:

### 开启 Storybook

可以直接使用如下命令开启 Storybook 功能。

```bash
$ npx modern new
? 请选择你想要的操作 启用可选功能
? 请选择功能名称 启用「Storybook」
```

该命令会创建好 Storybook 常用的模版，包括

- 创建 stories 组件示例
- 更新 package.json，新增依赖 @modern-js/plugin-storybook，以及添加 `pnpm dev storybook` 等相关脚本。

### 配置 Storybook

Storybook 官方通过一个名为 `.storybook` 的文件夹来进行项目配置，其中包含各种配置文件。**在 Modern.js Module 中，可以在项目的 `config/storybook` 目录下增加 Storybook 配置文件。**

关于 Storybook 各种配置文件的使用方式，可以查看下面的链接：

- [Configure Storybook](https://storybook.js.org/docs/react/configure/overview)

**不过这在模块项目里使用时存在一些限制**：

- 不能修改 Story 文件存放的位置，即无法在 `main.js` 文件里修改 `stories` 配置。
- 不能修改 Webpack 和 Babel 相关的配置，即无法在 `main.js` 文件里修改 `webpackFinal` 和 `babel` 配置。

### 构建 Storybook 产物

除了可以对组件或者普通的模块进行 Storybook 调试，还可以通过下面的命令来执行 Storybook 的构建任务。

```bash
modern build --platform storybook
```

构建完成后，可以在 `dist/storybook-static` 目录看到构建产物文件。
