StoryBook 开发 React 组件库文档
说明
StoryBook 是一个开源的 UI 组件库构建工具,支持 React、Vue、Angular 等主流开发框架,使用 StoryBook 将获得以下优势:
- 开发环境隔离并以可交互的方式展示组件
- 便捷且直观组件分组管理方式
- 同样使用 webpack 构建,集成 react-hot-loader 调试方便
- 可配置化程度高,插件化,社区完善
安装
# 安装主要依赖
npm install @storybook/react --save-dev
# 然后安装开发组件必要的package react react-dom babel-loader @babel/core 等
# 如果需要用到插件
npm install @storybook/addons --save-dev
# package.json 增加 scripts {"storybook": "start-storybook"}
# 启动项目
npm run storybook
将 StoryBook 集成到项目中
# 目录说明
├── .storybook/ # 配置文件目录
├ ├── addons.js # 插件注册文件
├ ├── .babelrc # 自定义 babel 配置
├ ├── config.js # 主配置文件
├ ├── customTheme.js # 自定义的主题
├ ├── layout.js # 主显示区域的布局
├ └── webpack.config.js #自定义 webpack 配置
1. 创建配置文件目录
在根文件夹下创建 .storybook/ 文件夹,StoryBook 的所有配置相关的文件都会放到这里
mkdir .storybook
2. 创建主配置文件
在 .storybook/ 下创建 config.js 配置文件,这里主要负责全局的一些配置,例如:
- 页面主题配置
- 插件安装
- 收集待展示的 stories (概念稍后说明)
注意:如 addParameters、addDecorator 在 .storybook/config.js 中进行的都是全局的操作,适用于全部的 story, 如果只应用于特定的 story 可以在 story 中进行配置
// .storybook/config.js
import { configure, addParameters, addDecorator } from '@storybook/react';
import {withInfo} from '@storybook/addon-info';
import customTheme from './customTheme';
// 1.
function loadStories() {
const req = require.context('../src/components', true, /\.stories\.js$/);
req.keys().forEach(filename => req(filename));
}
addParameters({
// 2.
options: {
showPanel: true,
panelPosition: 'right',
theme: customTheme
},
});
addDecorator(withInfo);
addDecorator(AreaWrapper)
configure(loadStories, module);
1. loadStories Function
是一个用来加载 stories 的函数
2. addParameters
追加参数,其值是一个对象,其中 key 为 options 的项是默认支持的,用来配置一些原有控件的展示情况,更多可查看Options Parameter
如果使用了某些插件,可能也需要通过 addParameters 方法追加参数 例如 storybook-readme 这个插件,可以追加参数来改变readme 中代码的展示主题
addParameters({
options: {
// ...
},
readme: {
codeTheme: 'hopscotch',
}
});
3. addDecorator
Decorator 是一个通用的包装组件的方式,许多插件的应用需要实现对组件的包装,我们也可以通过这个方法,实现对组件的包装,例如:增加边距,美化显示效果
const AreaWrapper = (storyFn) => (
<div style={{padding: '10px 20px'}}>
{storyFn()}
</div>
);
addDecorator(AreaWrapper)
4. 主题
内置 light 和 dark 两个主题,如果有定制化需要可以通过如下方式创建,更多查看Theming Storybook
import { create } from '@storybook/theming';
export default create({
base: 'light',
//...
brandTitle: 'XXX UI COMPONENTS',
brandUrl: 'https://xxx.xxx.com',
brandImage: 'https://cdn.xxx.com/common/static/img/Logo.svg'
});
3. 编写 story
story 就是”描述“,用来描述一个组件的使用流程,我们在 .storybook/config.js 中通过 loadStories 加载了指定的描述文件,现在我们来编写它
// src/components/LoadingButton/index.stories.js
import * as React from 'react';
import {storiesOf} from '@storybook/react';
// 引入插件
import {withKnobs} from '@storybook/addon-knobs';
// 引入组件
import {LoadingButton} from 'xxx-ui-components';
// 创建一个 story
storiesOf('Button/LoadingButton', module)
// 加插件
.addDecorator(withSmartKnobs)
.addDecorator(withKnobs)
// 加参数
.addParameters({
readme: {
content: ButtonReadme,
sidebar: ButtonUSAGE
},
})
// 加案例
.add('with text', () => {
return (
<LoadingButton
loading={false}
label={'sxxx'}
arr={array('arr', [])}
immutable={Immutable(object('immutable'))}
onClick={linkTo('XXX/Button', 'with emoji')}
>
Hello Button
</LoadingButton>
);
})
.add('with emoji', () => <BlankPage type={'NOT_FOUND'} />, {
options: { panelPosition: 'right' } // 可以有 第三个参数与 addParameters 类似,给每一个案例定制
});
4. 增加 addons
story 创建中会用到插件 addons, storybook 官方提供一部分插件,其他的是社区提供的
1. 注册插件
首先要在 .storybook/ 下创建 addons.js 插件注册文件,在这里是进行插件注册的,(并不是所有插件都需要注册,具体的要看插件的文档要求)
// .storybook/addons.js
import '@storybook/addons'
import '@storybook/addon-knobs/register';
import 'storybook-readme/register';
import '@storybook/addon-actions/register';
import '@storybook/addon-storysource/register';
import '@storybook/addon-a11y/register';
import '@storybook/addon-viewport/register';
import '@storybook/addon-links/register';
2. 插件配置
大部分插件可以选择是在全局安装还是在某一个 story 中安装
- 全局安装:.storybook/config.js 中通过 addDecorator(addon) 安装
- story安装:在某个 *.stories.js 中 storiesOf(‘XXX’, module).addDecorator(addon) 安装
同理,部分插件还需要进行参数的配置 这就会用到 addParameters() 方法
- 全局安装:.storybook/config.js 中通过 addParameters({[addonKey]: addonParam}) 追加
- story安装:在某个 *.stories.js 中 storiesOf(‘XXX’, module).addParameters({[addonKey]: addonParam}) 追加
5. 自定义构建
有的时候,我们想对打包构建做一些定制化的处理就需要更改 storybook 的 webpack | babel 配置,storybook 提供更改的接口
1. 自定义 .babelrc
在 .storybook/ 下创建 .babelrc 即可,他会覆盖 storybook 默认的babel 配置
{
"presets": [
["env", {
"modules": false,
"targets": {
"node": "current",
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}],
"flow",
"react",
"stage-2"
],
"plugins": [
"react-hot-loader/babel",
["import", [
{ "libraryName": "antd", "libraryDirectory": "es", "style": true }
]]
]
}
2. 自定义 webpack
在 .storybook/ 下创建 webpack.config.js 文件,与一般的 webpack 配置文件不同, 因为 storybook 本身已经实现了一套 webpack 配置,你需要做的是对其修改而不是重新写一套
- webpack 使用的是 4.x.x 版本
- config 文件的返回值是一个异步函数
- 异步函数接收两个参数 config:默认配置 mode 环境变量
- config 的 entry 与 output 不应该被更改
module.exports = async ({config, mode}) => {
config.resolve.extensions.push('.css');
config.resolve.modules.push(path.resolve(__dirname, '../src'));
config.module.rules.push({
test: /\.stories\.jsx?$/,
loader: require.resolve('@storybook/addon-storysource/loader'),
enforce: 'pre',
options: { parser: 'flow' },
});
config.plugins.push(
new webpack.ProvidePlugin({
React: 'react',
_: 'lodash'
})
);
return config
};