Storybook 同步
保持 Storybook story 与组件同步,部署活的设计系统文档站。
为什么
Storybook 是设计系统的活文档——交互展示每组件、每变体、每状态。story 与组件漂移时(加 prop 但无 story 覆盖),该 prop 对用 Storybook 规格功能的设计师和产品经理不可见。把 Storybook 部署为静态站(Chromatic 或自托管)给非工程师一个 URL 浏览设计系统无需跑应用。这是设计决策对照现实而非可能不匹配代码的 Figma 模型做的方式。同步通过 story 与组件同位置和 CI 在提交无 story 组件时失败来维护。
何时使用
有 ≥5 组件时。搭建 + 部署约 1-2 小时。无可复用组件的应用可跳过。
如何做
1. 用 React + Vite builder 装 Storybook - npx storybook@latest init --builder vite - story 同位置:Component.stories.tsx 紧邻 Component.tsx 2. 写覆盖每变体和状态的 story - props 用 args;交互测试用 play() 函数 - 含边界:空、加载、错误、禁用、长文本 3. 加 CI job 构建并部署 Storybook - 构建:npx storybook build -o storybook-static - 部署到 Chromatic(开源免费)或 Netlify/Vercel 作静态站 4. CI 加"无孤儿组件"检查 - 脚本:找 components/ 里无匹配 .stories.tsx 的 .tsx → 失败 - 这防组件无文档存在 5. 启用 Storybook addon:a11y、controls、docs、viewport - a11y 每故事跑 axe;违规 CI 失败 - viewport 测响应式行为无需单独测试套件
示例
// Button.stories.tsx
import type { Meta, StoryObj } from "@storybook/react";
import { Button } from "./Button";
const meta: Meta<typeof Button> = { title: "Atoms/Button", component: Button, tags: ["autodocs"], argTypes: { variant: { control: "select", options: ["primary", "secondary", "ghost"] } } };
export default meta;
export const Default: StoryObj<typeof Button> = { args: { children: "点我", variant: "primary" } };
export const Disabled: StoryObj<typeof Button> = { args: { children: "禁用", disabled: true } };
export const LongText: StoryObj<typeof Button> = { args: { children: "可能溢出的很长按钮标签" } };
// CI:.github/workflows/storybook.yml
- run: npx storybook build
- run: npx chromatic --project-token ${{ secrets.CHROMATIC_TOKEN }} --exit-zero-on-changes常见问题
- ⚠story 只覆盖快乐路径,错误和加载状态无文档无测试。
- ⚠不部署 Storybook,设计师不能浏览组件,一直问开发者'这长啥样?'。
- ⚠story 在单独 /stories 目录,重命名后与组件漂移。
- ⚠无 a11y addon,可访问性违规发到 prod 仅用户投诉才抓。
最佳实践
- ✓story 与组件同位置,重命名同时移两文件。
- ✓用交互测试(play 函数)验证行为非仅渲染——抓组件逻辑 bug。
- ✓每 PR 部署 Storybook(预览 URL),评审者合并前看组件变更。
- ✓加 'design' addon 把每 story 链到其 Figma 画板,事实源一键即达。