Storybook 简介 #
什么是 Storybook? #
Storybook 是一个开源的 UI 组件开发环境,它允许你在隔离的环境中开发、测试和展示 UI 组件。通过 Storybook,你可以独立于应用程序来构建组件,专注于组件的各个状态和变体。
核心定位 #
text
┌─────────────────────────────────────────────────────────────┐
│ Storybook │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 组件隔离 │ │ 交互式开发 │ │ 文档生成 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 组件测试 │ │ 插件生态 │ │ 多框架支持 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
Storybook 的历史 #
发展历程 #
text
2016年 ─── Storybook 项目启动
│
│ 由 Kadira 开发
│ 专注于 React 组件开发
│
2017年 ─── 开源发布
│
│ 转移到社区维护
│ 支持更多框架
│
2018年 ─── Storybook 4.0
│
│ 支持 Vue、Angular
│ 插件系统完善
│
2019年 ─── Storybook 5.0
│
│ 全新 UI 设计
│ 性能大幅提升
│
2020年 ─── Storybook 6.0
│
│ 零配置体验
│ CSF 3.0 格式
│
2022年 ─── Storybook 7.0
│
│ UI 全面升级
│ 原生 TypeScript 支持
│
2024年 ─── Storybook 8.0
│
│ 性能优化
│ 更好的测试集成
│
至今 ─── 行业标准
│
│ 超过 300 万周下载量
│ 企业级组件库首选
里程碑版本 #
| 版本 | 时间 | 重要特性 |
|---|---|---|
| 3.0 | 2017 | 开源发布,基础功能 |
| 4.0 | 2018 | 多框架支持(Vue、Angular) |
| 5.0 | 2019 | 全新 UI,性能优化 |
| 6.0 | 2020 | 零配置,CSF 3.0 |
| 7.0 | 2022 | UI 升级,原生 TypeScript |
| 8.0 | 2024 | 性能优化,测试增强 |
为什么选择 Storybook? #
传统组件开发的痛点 #
在没有 Storybook 之前,UI 组件开发面临以下问题:
text
┌─────────────────────────────────────────────────────────────┐
│ 传统开发的问题 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. 组件状态难以复现 │
│ - 需要在应用中导航到特定页面 │
│ - 需要特定的数据状态 │
│ - 难以测试边界情况 │
│ │
│ 2. 开发效率低下 │
│ - 每次修改都需要刷新整个应用 │
│ - 依赖复杂的应用状态 │
│ - 调试困难 │
│ │
│ 3. 组件文档缺失 │
│ - 组件使用方式不清晰 │
│ - 缺乏交互式示例 │
│ - 文档与代码不同步 │
│ │
│ 4. 团队协作困难 │
│ - 设计师难以查看组件 │
│ - 开发者之间缺乏沟通 │
│ - 组件复用率低 │
│ │
└─────────────────────────────────────────────────────────────┘
Storybook 的解决方案 #
text
┌─────────────────────────────────────────────────────────────┐
│ Storybook 的解决方案 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ✅ 组件隔离开发 │
│ - 独立于应用运行 │
│ - 专注于单个组件 │
│ - 快速迭代 │
│ │
│ ✅ 状态管理 │
│ - 每个状态一个 Story │
│ - 轻松切换不同状态 │
│ - 边界情况一目了然 │
│ │
│ ✅ 交互式文档 │
│ - 自动生成组件文档 │
│ - 实时编辑预览 │
│ - Props 探索 │
│ │
│ ✅ 团队协作 │
│ - 设计师可直接查看组件 │
│ - 开发者共享组件库 │
│ - 提高组件复用率 │
│ │
└─────────────────────────────────────────────────────────────┘
Storybook 的核心特点 #
1. 组件隔离开发 #
在独立环境中开发组件,不受应用其他部分的影响:
javascript
// Button.stories.js
import Button from './Button';
export default {
title: 'Components/Button',
component: Button,
};
export const Primary = {
args: {
variant: 'primary',
children: 'Primary Button',
},
};
export const Disabled = {
args: {
variant: 'primary',
disabled: true,
children: 'Disabled Button',
},
};
2. 多框架支持 #
Storybook 支持主流前端框架:
text
┌─────────────────────────────────────────────────────────────┐
│ 支持的框架 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ React │ │ Vue │ │ Angular │ │ Svelte │ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Web Components │ │ Solid │ │
│ └─────────────────┘ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
3. 丰富的插件生态 #
text
┌─────────────────────────────────────────────────────────────┐
│ 官方插件 │
├─────────────────────────────────────────────────────────────┤
│ │
│ @storybook/addon-essentials 核心插件集合 │
│ ├── Docs 自动文档生成 │
│ ├── Controls 动态参数控制 │
│ ├── Actions 事件日志 │
│ ├── Viewport 视口切换 │
│ ├── Backgrounds 背景切换 │
│ └── Measure/Outline 布局检查 │
│ │
│ @storybook/addon-interactions 交互测试 │
│ @storybook/addon-a11y 无障碍检查 │
│ @storybook/addon-coverage 代码覆盖率 │
│ │
└─────────────────────────────────────────────────────────────┘
4. 自动文档生成 #
javascript
// 自动从组件生成文档
export default {
title: 'Components/Button',
component: Button,
tags: ['autodocs'], // 启用自动文档
argTypes: {
variant: {
control: 'select',
options: ['primary', 'secondary', 'danger'],
description: '按钮变体类型',
},
size: {
control: 'radio',
options: ['small', 'medium', 'large'],
description: '按钮尺寸',
},
},
};
5. 测试集成 #
text
┌─────────────────────────────────────────────────────────────┐
│ 测试能力 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 组件测试(Component Testing) │
│ ├── 交互测试 │
│ ├── 状态验证 │
│ └── 用户行为模拟 │
│ │
│ 视觉测试(Visual Testing) │
│ ├── 快照对比 │
│ ├── 视觉回归测试 │
│ └── 跨浏览器测试 │
│ │
│ 无障碍测试(Accessibility Testing) │
│ ├── A11y 规则检查 │
│ ├── 键盘导航测试 │
│ └── 屏幕阅读器兼容 │
│ │
└─────────────────────────────────────────────────────────────┘
Storybook 的应用场景 #
1. 组件库开发 #
text
┌─────────────────────────────────────────────────────────────┐
│ 组件库开发流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 设计系统 │
│ │ │
│ ▼ │
│ ┌─────────┐ │
│ │ Storybook │ ◄─── 组件开发、测试、文档 │
│ └─────┬─────┘ │
│ │ │
│ ▼ │
│ ┌─────────┐ │
│ │ NPM 包 │ ◄─── 发布组件库 │
│ └─────┬─────┘ │
│ │ │
│ ▼ │
│ ┌─────────┐ │
│ │ 应用 │ ◄─── 多个应用复用 │
│ └─────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
2. 设计系统落地 #
javascript
// 设计令牌集成
export const ThemeColors = {
render: () => (
<div style={{ display: 'grid', gap: '10px' }}>
{Object.entries(theme.colors).map(([name, value]) => (
<div key={name} style={{ display: 'flex', alignItems: 'center' }}>
<div style={{
width: 50,
height: 50,
background: value,
borderRadius: 4
}} />
<span style={{ marginLeft: 10 }}>{name}: {value}</span>
</div>
))}
</div>
),
};
3. 团队协作 #
text
┌─────────────────────────────────────────────────────────────┐
│ 团队协作流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 设计师 开发者 │
│ │ │ │
│ │ 设计稿 │ │
│ │────────────────────────>│ │
│ │ │ │
│ │ │ 在 Storybook 中开发 │
│ │ │ 实时预览 │
│ │ │ │
│ │ 查看组件 │ │
│ │<────────────────────────│ │
│ │ │ │
│ │ 反馈修改 │ │
│ │────────────────────────>│ │
│ │ │ │
│ │ │ 迭代优化 │
│ │ │ │
│ │
└─────────────────────────────────────────────────────────────┘
4. 文档站点 #
javascript
// .storybook/main.js
export default {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
addons: [
'@storybook/addon-essentials',
'@storybook/addon-interactions',
],
docs: {
autodocs: true,
},
};
Storybook 与其他工具对比 #
Storybook vs Styleguidist #
| 特性 | Storybook | Styleguidist |
|---|---|---|
| 组件隔离 | ✅ 完全隔离 | ⚠️ 部分隔离 |
| 交互开发 | ✅ 强大 | ⚠️ 基础 |
| 插件生态 | ✅ 丰富 | ⚠️ 有限 |
| 多框架支持 | ✅ 广泛 | ⚠️ React |
| 测试支持 | ✅ 完善 | ❌ 无 |
| 学习曲线 | ⚠️ 较陡 | ✅ 平缓 |
Storybook vs Docz #
| 特性 | Storybook | Docz |
|---|---|---|
| 组件隔离 | ✅ 完全隔离 | ⚠️ 部分隔离 |
| 交互开发 | ✅ 强大 | ⚠️ 基础 |
| 插件生态 | ✅ 丰富 | ⚠️ 有限 |
| MDX 支持 | ✅ 支持 | ✅ 原生 |
| 构建速度 | ⚠️ 较慢 | ✅ 快速 |
| 功能完整度 | ✅ 完善 | ⚠️ 基础 |
Storybook 的核心概念 #
Story #
Story 是组件的一个特定状态:
javascript
// 一个组件可以有多个 Story
export const Primary = {}; // 主要状态
export const Secondary = {}; // 次要状态
export const Disabled = {}; // 禁用状态
export const Loading = {}; // 加载状态
CSF(Component Story Format) #
Storybook 的标准格式:
javascript
// Button.stories.js
import Button from './Button';
// 默认导出:组件配置
export default {
title: 'Components/Button',
component: Button,
tags: ['autodocs'],
};
// 命名导出:各个 Story
export const Primary = {
args: {
variant: 'primary',
children: 'Primary Button',
},
};
Decorators #
装饰器用于包装组件:
javascript
export default {
title: 'Components/Card',
component: Card,
decorators: [
(Story) => (
<div style={{ padding: 20 }}>
<Story />
</div>
),
],
};
Addons #
插件扩展 Storybook 功能:
javascript
// .storybook/main.js
export default {
addons: [
'@storybook/addon-essentials',
'@storybook/addon-interactions',
'@storybook/addon-a11y',
],
};
Storybook 的优势与局限 #
优势 #
text
✅ 组件隔离开发
- 独立于应用运行
- 专注于单个组件
- 快速迭代
✅ 丰富的插件生态
- 官方插件完善
- 社区插件丰富
- 可自定义插件
✅ 自动文档生成
- 减少文档维护成本
- 文档与代码同步
- 交互式文档
✅ 测试集成
- 组件测试
- 视觉测试
- 无障碍测试
✅ 多框架支持
- React、Vue、Angular
- Svelte、Solid
- Web Components
局限性 #
text
⚠️ 学习曲线
- 概念较多
- 配置复杂
- 需要时间熟悉
⚠️ 构建时间
- 大型项目启动较慢
- 需要优化配置
- 热更新可能延迟
⚠️ 环境差异
- 与真实应用环境可能不同
- 需要正确配置上下文
- 某些功能需要 Mock
⚠️ 维护成本
- 需要维护 Stories
- 配置需要更新
- 插件版本管理
学习路径 #
text
入门阶段
├── Storybook 简介(本文)
├── 安装与配置
└── 基础使用
进阶阶段
├── 编写 Stories
├── 插件系统
└── 组件测试
高级阶段
├── 装饰器与参数
├── 自定义插件
└── 性能优化
实战阶段
├── 组件库开发
├── 设计系统落地
└── CI/CD 集成
下一步 #
现在你已经了解了 Storybook 的基本概念,接下来学习 安装与配置 开始实际使用 Storybook!
最后更新:2026-03-29