背景
目前部门内部正在推动工程化建设与技术栈迁移(Preact->React),因此许多旧项目就需要进行重构,原本封装的各种UI组件也都是依赖于Preact框架,且都是单独的npm包形式存在,代码风格各异,没有一个统一的UI组件查询平台,基于此,我们决定建设一个统一的UI组件库。
目标
-
组件可视化(支持多平台H5/PC)
-
自动生成API文档,较少的书写文档工作量
组件文档方案调研
官方介绍:
react-docgen 是一个 CLI 和工具箱,可帮助从 React 组件中提取信息并从中生成文档。它使用 AST 类型和@babel/parser 将源解析为 AST,并提供处理此 AST 的方法以提取所需的信息。输出/返回值是一个 JSON blob/JavaScript 对象。
也就是说它能够提取组件的一些关键信息,我们再根据这些信息转化为 markdown,最后依据这些 markdown 生成组件说明文档。没有组件预览,且额外工作量较多,pass
这是一个基于 MDX 文件生成组件文档的库,你可以在每个组件内部自动添加 mdx 文件, Docz 会自动将其转化部署生成文档库。仍然需要自己书写 mdx 文件,pass
Storybook(star: 57.2k) 与 Styleguidist(React-Styleguidist star: 9.5k) 都是很完备的组件文档自动生成方案,支持组件预览与组件交互状态展示等,支持组件 API 文档自动生成。同时,Storybook 相对于 Styleguidist 还有以下优点:
- 支持移动端预览
- 支持更多框架更丰富(React/Vue/Angular/Web Component/Ember/HTML/Mithril/Marko/Svelte/Riot/Preact/Rax/RN等)
设计开发
- 首先在项目中安装 storybook 依赖,如下为我们项目中安装的 storybook 相关依赖与插件, storybook 提供了一个丰富的插件市场,可以丰富组件库平台功能。
"devDependencies": {
"@storybook/addon-actions": "^6.0.28",
"@storybook/addon-console": "^1.2.2",
"@storybook/addon-essentials": "^6.0.28",
"@storybook/addon-links": "^6.0.28",
"@storybook/addons": "^6.0.28",
"@storybook/react": "^6.0.28",
"@storybook/theming": "^6.0.28",
}
- 安装 storybook 后项目中会增加一个 .storybook 的文件夹,里边包含了一些 storybook 的基本配置
// main.js storybook 打包构建配置文件
module.exports = {
// 需要打包构建生成文档文件所在文件夹
stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
// 需要启用的第三方 addons
addons: ['@storybook/addon-links', '@storybook/addon-essentials'],
// storybook 已经包含一份基本的 webpack 配置,同时支持自定义配置项
webpackFinal: async (config) => {
config.devtool = false;
config.performance = {
hints: false,
maxEntrypointSize: 512000,
maxAssetSize: 512000,
};
return config;
},
};
// manager.js 组件库基本主题样式配置文件
import { addons } from '@storybook/addons';
import { create } from '@storybook/theming';
addons.setConfig({
showRoots: true,
theme: create({
base: 'light',
brandUrl: '***',
// brandImage: 'https://y.qq.com/favicon.ico',
brandTitle: 'QQ音乐UI组件库',
}),
});
- 组件开发与文档生成
组件目录结构
.
├── Avatar.stories.tsx
├── index.tsx
└── style
└── index.css
组件入口文件 index.tsx
import * as React from 'react';
import { fixUrl } from '../libs/pic';
// 组件 Props 定义,storybook 会据此生成 API 说明文档(支持PropsType)
export interface IAvatarProps {
/**
* 头像尺寸 // 该字段用于描述组件参数 Description
*/
size: number;
/**
* 头像链接
*/
avatarUrl: string;
/**
* alt属性
*/
altName?: string;
}
/**
* 这里还可以添加组件自定义说明
*
*/
export const Avatar: React.FunctionComponent<IAvatarProps> = (props) => {
const { size = Avatar.defaultProps.size, avatarUrl, altName = Avatar.defaultProps.altName } = props;
return (
<img
style={{ display: 'block', width: size, height: size, borderRadius: size }}
src={fixUrl(avatarUrl)}
alt={altName || '用户头像'}
/>
);
};
// 组件默认参数
Avatar.defaultProps = {
size: 100,
altName: '头像',
};
storybook 文件 A.ctories.tsx
import React from 'react';
import { Story, Meta } from '@storybook/react/types-6-0';
import { IAvatarProps, Avatar } from './index';
// 定义组件分组/tab名称
export default {
title: '数据展示/Avatar 头像',
component: Avatar,
argTypes: {},
} as Meta;
// 组件预览 Demo,支持多个 demo 预览
const Template: Story<IAvatarProps> = (args) => <Avatar {...args} />;
export const 头像 = Template.bind({});
头像.args = {
size: 100,
avatarUrl: 'https://y.gtimg.cn/music/photo_new/T001R150x150M000002lO5Lc1GCmvn_2.jpg',
altName: 'nickName',
};
- 执行
yarn run storybook直接在浏览器预览效果,切换到 canvas 标签栏,可以直接修改组件参数,组件预览会实时更新。
- 添加组件库使用说明文档,支持 MDX 文档
// index.stories.mdx
import { Meta } from '@storybook/addon-docs/blocks';
// 分组名称信息设置
<Meta title="介绍/Getting started" />
# Getting Started
## 使用
以`Input`组件为例说明
import { Input } from '***';
- 文档打包发布
运行 yarn run build-storybook 会在根目录生成 storybook-static 文档产物,直接发布构建产物即可。