Skip to content

Storybook 集成

什么是 Storybook

Storybook 是一个开源工具,用于独立构建、测试和文档化 UI 组件。它为开发者提供了一个独立于主应用程序的环境,使组件开发更加高效和有条理。

主要特点

  • 隔离环境:在应用程序上下文之外开发 UI 组件
  • 组件驱动开发:专注于一次构建一个组件
  • 可视化测试:直观地检查组件在不同状态下的外观
  • 交互式文档:创建活跃的、可交互的组件文档
  • 插件生态系统:通过众多插件扩展功能

使用场景

  • 创建设计系统或组件库
  • 开发复杂的 UI 界面
  • 测试组件的边缘情况
  • 协作开发(设计师和开发者)

项目集成

Storybook 的 cli 貌似不太好用,这边提供一个将 Storybook 与 Vite 项目集成的方案。

环境要求

  • bun
  • React ≥ 16.8
  • Vite ≥ 4.0
  • Storybook ≥ 8.0

创建项目

bash
$ bun create vite
reused 0, downloaded 1, added 1, done
|
o  Project name:
|  storybook-demo
|
o  Select a framework:
|  React
|
o  Select a variant:
|  TypeScript + SWC
|
o  Scaffolding project in D:\Projects\storybook-demo...
|
  Done. Now run:

  cd storybook-demo
  bun install
  bun run dev

$ bun install
...

项目结构:

bash
$ tree
.
|-- README.md
|-- eslint.config.js
|-- index.html
|-- package.json
|-- public
|   `-- vite.svg
|-- src
|   |-- App.css
|   |-- App.tsx
|   |-- assets
|   |   `-- react.svg
|   |-- index.css
|   |-- main.tsx
|   `-- vite-env.d.ts
|-- tsconfig.app.json
|-- tsconfig.json
|-- tsconfig.node.json
`-- vite.config.ts

3 directories, 15 files

vite create 默认没有创建库项目的选项,下面我们将这个项目改造成库项目。

先删掉 src/ 下的 css、ts 和资源文件,创建一个空的 index.ts 文件,现在项目结构长这样:

bash
$ tree
.
|-- README.md
|-- eslint.config.js
|-- index.html
|-- package.json
|-- src
|   |-- index.ts
|   `-- vite-env.d.ts
|-- tsconfig.app.json
|-- tsconfig.json
|-- tsconfig.node.json
`-- vite.config.ts

2 directories, 11 files

修改 vite.config.ts 文件,将项目类型改为库项目:

ts
import { defineConfig } from 'vite'

import react from '@vitejs/plugin-react-swc'

// https://vite.dev/config/
export default defineConfig({
  plugins: [react()],
  // 新增以下配置
  build: {
    lib: {
      entry: 'src/index.ts',
      name: 'my-components',
      formats: ['es'],
    }
  }
})

记得安装一下 sass 依赖,我们接下来要使用 scss 编写样式:

bash
$ bun add -D sass-embedded
Packages: +20
++++++++++++++++++++
Progress: resolved 483, reused 403, downloaded 7, added 20, done

devDependencies:
+ sass-embedded 1.86.3

Done in 7.2s

现在就是一个 React 库项目咯,可以开始集成 Storybook 了。

集成 Storybook

安装 Storybook:

bash
// 安装 Storybook 时会调用 npm 安装一些包,如果 npm 环境有问题可以加上 --package-manager=bun
$ bun create storybook@latest
╭───────────────────────────────────────────────────────╮

   Adding Storybook version 8.6.12 to your project..

╰───────────────────────────────────────────────────────╯
 What do you want to use Storybook for? » Documentation: MDX, auto-generated component docs, Testing: Fast browser-based component tests, watch mode
 Detecting project type.
Installing dependencies...

Lockfile is up to date, resolution step is skipped
Already up to date
Done in 678ms
 Adding Storybook support to your "React" app Detected Vite project. Setting builder to Vite.

 Getting the correct version of 0 packages
.
Installing dependencies...

Lockfile is up to date, resolution step is skipped
Already up to date
Done in 750ms
> npx [email protected] add @storybook/[email protected]
Verifying @storybook/experimental-addon-test
Installing @storybook/experimental-addon-test@^8.6.12
Adding '@storybook/[email protected]' to the "addons" field in .storybook\main.ts
Running postinstall script for @storybook/experimental-addon-test

 👋 Howdy! ─────────────────────────────────────────────────────────────────╮

   I\'m the installation helper for @storybook/experimental-addon-test

   Hold on for a moment while I look at your project and get it set up...

╰────────────────────────────────────────────────────────────────────────────╯

 Configuring Playwright with Chromium (this might take some time):
  npx playwright install chromium --with-deps

 🚨 Oh no! ──────────────────────────────────────────────────────────────╮

   Found an existing Vitest setup file:
   D:/Projects/storybook-demo/.storybook/vitest.setup.ts

   Please refer to the documentation to complete the setup manually:
   https://storybook.js.org/docs/writing-tests/test-addon#manual-setup

╰─────────────────────────────────────────────────────────────────────────╯

╭──────────────────────────────────────────────────────────────────────────────╮

   Storybook was successfully installed in your project! 🎉
   Additional features: Documentation, Testing

   To run Storybook manually, run bun run storybook. CTRL+C to stop.

   Wanna know more about Storybook? Check out https://storybook.js.org/
   Having trouble or want to chat? Join us at https://discord.gg/storybook/

╰──────────────────────────────────────────────────────────────────────────────╯

Running Storybook

> [email protected] storybook D:\Projects\storybook-demo
> storybook dev -p 6006 "--initial-path=/onboarding" "--quiet"

@storybook/core v8.6.12

info => Serving static files from D:\Projects\storybook-demo\node_modules\.cache\storybook\default\coverage at /coverage
info Using tsconfig paths for react-docgen
17:58:40 [vite] (client) hmr update /@id/__x00__virtual:/@storybook/builder-vite/vite-app.js

这里会自动打开 Storybook 的欢迎页面,按照指引操作即可。(注意让你命名新 stories 时不要和已有的 stories 重名)

完成上述操作以后的项目结构如下:

bash
$ tree -F -I "node_modules"
.
|-- README.md
|-- eslint.config.js
|-- index.html
|-- package.json
|-- bun-lock.yaml
|-- src/
|   |-- index.ts
|   |-- stories/
|   |   |-- Button.stories.ts
|   |   |-- Button.tsx
|   |   |-- Configure.mdx
|   |   |-- Header.stories.ts
|   |   |-- Header.tsx
|   |   |-- Page.stories.ts
|   |   |-- Page.tsx
|   |   |-- assets/
|   |   |   |-- accessibility.png
|   |   |   |-- accessibility.svg
|   |   |   |-- addon-library.png
|   |   |   |-- assets.png
|   |   |   |-- avif-test-image.avif
|   |   |   |-- context.png
|   |   |   |-- discord.svg
|   |   |   |-- docs.png
|   |   |   |-- figma-plugin.png
|   |   |   |-- github.svg
|   |   |   |-- share.png
|   |   |   |-- styling.png
|   |   |   |-- testing.png
|   |   |   |-- theming.png
|   |   |   |-- tutorials.svg
|   |   |   `-- youtube.svg
|   |   |-- button.css
|   |   |-- header.css
|   |   `-- page.css
|   `-- vite-env.d.ts
|-- tsconfig.app.json
|-- tsconfig.json
|-- tsconfig.node.json
|-- vite.config.ts
`-- vitest.workspace.ts

3 directories, 38 files

我们先暂时忽略一下 src/stories/ 目录,在 src/components 中创建 Button 文件夹并添加如下几个文件:

bash
$ tree ./src/components/Button/
./src/components/Button/
|-- Button.scss
|-- Button.stories.ts
|-- Button.test.ts
|-- Button.tsx
`-- index.ts

0 directories, 5 files

Button.tsx 文件可以直接复制 stories/Button.tsx 的内容,只要将首行的 import 语句导入的样式文件后缀名改成 scss 即可,Button.stories.ts 文件可以直接复制 stories/Button.stories.ts 的内容,Button.scss 文件也可以直接复制 stories/Button.css 的内容,因为 scss 是 css 的超集,可以无缝转换 ,Button.test.ts 文件暂时先不管,这里是组件测试的代码,笔者还没研究。

现在在 src\Button\index.ts 中导出组件:

ts
import { Button } from './Button';

export default Button;
export type { ButtonProps } from './Button';

src/index.ts 中导出组件:

ts
export { default as Button } from './components/Button';

现在可以把 src/stories 目录删掉啦,需要抄的代码已经抄完了,可以不用它了。删掉之前可以先看一看 src\stories\Configure.mdx 的内容,学习一下怎么使用 MDX 书写组件库文档。

完成后的项目结构:

bash
$ tree -F -I "node_modules"
.
|-- README.md
|-- eslint.config.js
|-- index.html
|-- package.json
|-- bun-lock.yaml
|-- src/
|   |-- components/
|   |   `-- Button/
|   |       |-- Button.scss
|   |       |-- Button.stories.ts
|   |       |-- Button.test.ts
|   |       |-- Button.tsx
|   |       `-- index.ts
|   |-- index.ts
|   `-- vite-env.d.ts
|-- tsconfig.app.json
|-- tsconfig.json
|-- tsconfig.node.json
|-- vite.config.ts
`-- vitest.workspace.ts

3 directories, 17 files

现在就已经可以愉快的书写组件库啦😋,接下来我们来看看 Storybook 的使用。

Storybook 使用

在重构项目结构以后,打开 package.json,可以看到现在的脚本如下:

json
{
  ...,
  "scripts": {
    "dev": "vite",
    "build": "tsc -b && vite build",
    "lint": "eslint .",
    "preview": "vite preview",
    "storybook": "storybook dev -p 6006",
    "build-storybook": "storybook build"
  },
  ...
}

由于现在的项目是一个库项目,无法直接使用 vite 命令运行,所以我们可以稍作修改:

json
{
  ...,
  "scripts": {
    "dev": "storybook dev -p 6006",
    "lint": "eslint .",
    "build": "bun run build:js && bun run build:types && bun run build:css",
    "build:js": "vite build",
    "build:types": "tsc --emitDeclarationOnly",
    "build:storybook": "storybook build"
  },
  ...
}

现在运行 bun dev 就可以直接启动 Storybook 开发服务器啦,快去试试吧🎉

Last updated: