Storybook 安装与配置 #
安装方式 #
自动安装(推荐) #
在现有项目中快速安装 Storybook:
bash
# 进入项目目录
cd my-project
# 自动安装 Storybook
npx storybook@latest init
安装过程会:
text
┌─────────────────────────────────────────────────────────────┐
│ 自动安装流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. 检测项目框架 │
│ ├── React │
│ ├── Vue │
│ ├── Angular │
│ ├── Svelte │
│ └── Web Components │
│ │
│ 2. 安装依赖 │
│ ├── @storybook/react │
│ ├── @storybook/addon-essentials │
│ └── 其他必需依赖 │
│ │
│ 3. 创建配置文件 │
│ ├── .storybook/main.js │
│ ├── .storybook/preview.js │
│ └── 示例 Stories │
│ │
│ 4. 添加脚本命令 │
│ ├── storybook (启动开发服务器) │
│ └── build-storybook (构建静态站点) │
│ │
└─────────────────────────────────────────────────────────────┘
手动安装 #
如果需要更多控制,可以手动安装:
bash
# 安装核心依赖
npm install --save-dev @storybook/react @storybook/react-webpack5
# 安装必需插件
npm install --save-dev @storybook/addon-essentials
# 创建配置目录
mkdir -p .storybook
不同框架的安装 #
React 项目 #
bash
# React + Webpack
npx storybook@latest init --builder webpack5
# React + Vite
npx storybook@latest init --builder vite
Vue 项目 #
bash
# Vue 3
npx storybook@latest init
# Vue 2(需要指定版本)
npm install --save-dev @storybook/vue@6
Angular 项目 #
bash
npx storybook@latest init
Svelte 项目 #
bash
npx storybook@latest init
项目结构 #
安装完成后,项目结构如下:
text
my-project/
├── .storybook/
│ ├── main.js # 主配置文件
│ ├── preview.js # 预览配置
│ └── theme.js # 主题配置(可选)
├── src/
│ ├── components/
│ │ ├── Button.jsx
│ │ └── Button.stories.jsx
│ └── stories/
│ └── Introduction.stories.mdx
└── package.json
配置文件详解 #
main.js - 主配置文件 #
主配置文件定义 Storybook 的核心行为:
javascript
// .storybook/main.js
/** @type { import('@storybook/react-vite').StorybookConfig } */
const config = {
// Stories 文件位置
stories: [
'../src/**/*.mdx',
'../src/**/*.stories.@(js|jsx|mjs|ts|tsx)',
],
// 插件配置
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-interactions',
],
// 文档配置
docs: {
autodocs: 'tag',
},
// 构建工具
framework: {
name: '@storybook/react-vite',
options: {},
},
// Vite 配置(如果使用 Vite)
async viteFinal(config) {
return {
...config,
// 自定义 Vite 配置
};
},
};
export default config;
配置选项详解 #
stories - Stories 文件路径 #
javascript
stories: [
// MDX 文档
'../src/**/*.mdx',
// Stories 文件
'../src/**/*.stories.@(js|jsx|mjs|ts|tsx)',
// 特定目录
'../src/components/**/*.stories.@(js|jsx|ts|tsx)',
],
addons - 插件配置 #
javascript
addons: [
// 核心插件集合
'@storybook/addon-essentials',
// 交互测试
'@storybook/addon-interactions',
// 链接插件
'@storybook/addon-links',
// 带选项的插件
{
name: '@storybook/addon-docs',
options: {
configureJSX: true,
},
},
],
framework - 框架配置 #
javascript
// React + Vite
framework: {
name: '@storybook/react-vite',
options: {},
},
// React + Webpack
framework: {
name: '@storybook/react-webpack5',
options: {},
},
// Vue 3 + Vite
framework: {
name: '@storybook/vue3-vite',
options: {},
},
// Angular
framework: {
name: '@storybook/angular',
options: {},
},
preview.js - 预览配置 #
预览文件用于配置全局设置:
javascript
// .storybook/preview.js
/** @type { import('@storybook/react').Preview } */
const preview = {
// 全局参数
parameters: {
// 布局配置
layout: 'centered',
// 背景配置
backgrounds: {
default: 'light',
values: [
{ name: 'light', value: '#ffffff' },
{ name: 'dark', value: '#333333' },
{ name: 'brand', value: '#1890ff' },
],
},
// 视口配置
viewport: {
viewports: {
mobile: {
name: 'Mobile',
styles: { width: '375px', height: '812px' },
},
tablet: {
name: 'Tablet',
styles: { width: '768px', height: '1024px' },
},
desktop: {
name: 'Desktop',
styles: { width: '1280px', height: '800px' },
},
},
},
// 操作配置
actions: { argTypesRegex: '^on[A-Z].*' },
// 控件配置
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
},
// 全局装饰器
decorators: [
(Story) => (
<div style={{ margin: '1em' }}>
<Story />
</div>
),
],
// 全局类型定义
argTypes: {
// 全局参数类型
},
// 标签
tags: ['autodocs'],
};
export default preview;
TypeScript 支持 #
配置 TypeScript #
javascript
// .storybook/main.js
const config = {
typescript: {
// 检查类型错误
check: false,
// React Docgen 配置
reactDocgen: 'react-docgen-typescript',
reactDocgenTypescriptOptions: {
shouldExtractLiteralValuesFromEnum: true,
propFilter: (prop) =>
prop.parent ? !/node_modules/.test(prop.parent.fileName) : true,
},
},
};
类型定义 #
typescript
// .storybook/main.ts
import type { StorybookConfig } from '@storybook/react-vite';
const config: StorybookConfig = {
stories: ['../src/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
addons: ['@storybook/addon-essentials'],
framework: {
name: '@storybook/react-vite',
options: {},
},
};
export default config;
typescript
// .storybook/preview.ts
import type { Preview } from '@storybook/react';
const preview: Preview = {
parameters: {
actions: { argTypesRegex: '^on[A-Z].*' },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
},
};
export default preview;
构建工具配置 #
Vite 配置 #
javascript
// .storybook/main.js
const config = {
async viteFinal(config) {
// 合并自定义配置
return {
...config,
resolve: {
...config.resolve,
alias: {
...config.resolve?.alias,
'@': path.resolve(__dirname, '../src'),
},
},
css: {
...config.css,
modules: {
localIdentName: '[name]__[local]--[hash:base64:5]',
},
},
};
},
};
Webpack 配置 #
javascript
// .storybook/main.js
const config = {
webpackFinal: async (config) => {
// 修改 webpack 配置
config.module.rules.push({
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader'],
});
// 添加别名
config.resolve.alias = {
...config.resolve.alias,
'@': path.resolve(__dirname, '../src'),
};
return config;
},
};
环境变量 #
配置环境变量 #
javascript
// .storybook/main.js
const config = {
env: (config) => ({
...config,
API_URL: process.env.API_URL || 'https://api.example.com',
FEATURE_FLAG: process.env.FEATURE_FLAG || 'false',
}),
};
使用环境变量 #
javascript
// .storybook/preview.js
const preview = {
parameters: {
API_URL: process.env.API_URL,
},
};
bash
# 启动时设置环境变量
API_URL=https://dev.api.com npm run storybook
主题定制 #
自定义主题 #
javascript
// .storybook/theme.js
import { create } from '@storybook/theming';
export default create({
// 基础主题
base: 'light',
// 品牌颜色
colorPrimary: '#1890ff',
colorSecondary: '#52c41a',
// UI 颜色
appBg: '#ffffff',
appContentBg: '#ffffff',
appBorderColor: '#e8e8e8',
appBorderRadius: 4,
// 文字颜色
textColor: '#333333',
textInverseColor: '#ffffff',
// 工具栏
barTextColor: '#999999',
barSelectedColor: '#1890ff',
barBg: '#ffffff',
// 品牌标识
brandTitle: 'My Component Library',
brandUrl: 'https://example.com',
brandImage: '/logo.svg',
});
应用主题 #
javascript
// .storybook/manager.js
import { addons } from '@storybook/manager-api';
import theme from './theme';
addons.setConfig({
theme: theme,
});
启动命令 #
开发模式 #
bash
# 启动开发服务器
npm run storybook
# 或使用 npx
npx storybook dev
# 指定端口
npx storybook dev -p 6007
# 指定主机
npx storybook dev -h 0.0.0.0
# 静态文件目录
npx storybook dev -s ./public
构建静态站点 #
bash
# 构建静态文件
npm run build-storybook
# 或使用 npx
npx storybook build
# 指定输出目录
npx storybook build -o dist-storybook
# 静态文件目录
npx storybook build -s ./public
package.json 脚本 #
json
{
"scripts": {
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build",
"test-storybook": "test-storybook",
"test-storybook:ci": "concurrently -k -s first \"npm run storybook\" \"wait-on http://localhost:6006 && npm run test-storybook\""
}
}
常见问题 #
1. 模块解析问题 #
javascript
// .storybook/main.js
const config = {
viteFinal: async (config) => {
config.resolve = {
...config.resolve,
alias: {
'@': path.resolve(__dirname, '../src'),
'@components': path.resolve(__dirname, '../src/components'),
},
};
return config;
},
};
2. CSS 模块问题 #
javascript
// .storybook/main.js
const config = {
viteFinal: async (config) => {
config.css = {
...config.css,
modules: {
localIdentName: '[name]__[local]--[hash:base64:5]',
},
};
return config;
},
};
3. 全局样式导入 #
javascript
// .storybook/preview.js
import '../src/styles/global.css';
import '../src/styles/variables.css';
const preview = {
// ...
};
export default preview;
4. Context Provider 配置 #
javascript
// .storybook/preview.js
import { ThemeProvider } from '../src/theme';
import { I18nProvider } from '../src/i18n';
const preview = {
decorators: [
(Story) => (
<ThemeProvider>
<I18nProvider>
<Story />
</I18nProvider>
</ThemeProvider>
),
],
};
export default preview;
最佳实践 #
1. 配置文件组织 #
text
.storybook/
├── main.js # 主配置
├── preview.js # 预览配置
├── manager.js # 管理器配置
├── theme.js # 主题配置
└── middleware.js # 中间件(可选)
2. 环境区分 #
javascript
// .storybook/main.js
const isProduction = process.env.NODE_ENV === 'production';
const config = {
viteFinal: async (config) => {
if (isProduction) {
config.build = {
...config.build,
minify: true,
};
}
return config;
},
};
3. 性能优化 #
javascript
// .storybook/main.js
const config = {
features: {
// 启用快速刷新
storyStoreV7: true,
},
core: {
builder: '@storybook/builder-vite',
},
};
下一步 #
现在你已经完成了 Storybook 的安装与配置,接下来学习 基础使用 开始编写你的第一个 Story!
最后更新:2026-03-29