市面上已经有很多成熟的React 组件库了,诸如 antd-design,semi-design 等等,覆盖了很多业务场景,一般已经足够我们使用了,但是掌握组件库开发流程也是有必要的,总会有需要沉淀业务组件的时候。
市面上比较流行的 2 个组件库工具分别的 dumi 和 Storybook:
- dumi,是一款为组件开发场景而生的文档工具,与 father 一起为开发者提供一站式的组件开发体验,father 负责构建,而 dumi 负责组件开发及组件文档生成。
- Storybook 是一个用于单独构建 UI 组件和页面的前端工具。成千上万的团队将它用于 UI 开发、测试和文档。它是开源和免费的。
dumi 和 Storybook 都是专用于组件开发场景的工具,由于 Storybook 更加支持测试难以到达的状态和边缘案例,因此最终选择 Storybook 来开发组件库。
1. 坏境搭建
1.1 新建项目
使用 creat-react-app 创建一个支持 TypeScript 的 React 项目。
npx create-react-app my-react-component --template typescript
此时通过 npm start,将在本地启动项目并输出地址。根据您的系统配置,它会自动在新的浏览器选项卡中打开地址,然后您会看到一个React 初始页面,说明项目构建成功。
1.2 为 React 项目添加 Storybook 能力
Storybook 教程:storybook.js.org/。
cd ./my-react-component
npx storybook init
FAQ
这里初始化时storybook有报错提示:TypeError: Invalid version. Must be a string. Got type "undefined"。这是一个BUG,到2023年8月17日这天都还没解决,详情可查看 issues。
1.2 代码规范
下列配置这里就不赘述了,网上有很多参考资料,可自行查阅。
1.2.1 Prettier
参考:Prettier配置指南
1.2.2 Eslint
参考:ESLint 配置文件
1.2.3 lint-staged
参考:[前端工程化配置] husky + lint-staged 格式化git提交代码
1.2.4 husky
参考 1.2.3 lint-staged 的推荐文章
1.2.5 commitlint
参考:commitlint配置
新增组件
在 src 目录下新增组件,每个组件包含 4 个基础文件:
- [component-name].tsx:组件代码
- [component-name].less:组件样式
- index.ts:组件需要导出的内容
- [component-name].stories.mdx:组件案例,Storybook 特定语法,组件案例在 npm start 后可以在线查看效果
打包组件库
- 安装webpack的相关包
yarn add webpack webpack-cli clean-webpack-plugin --save
- 根目录下添加 webpack.config.js
const path = require('path');
const fs = require('fs');
const paths = require('./paths');
const webpack = require('webpack');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const useTypeScript = fs.existsSync(paths.appTsConfig);
module.exports = {
mode: 'production',
entry: {
index: './stories/index.js',
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, "lib"),
publicPath: "/assets/",
libraryTarget: 'umd'
},
module: {
rules: [
{
test: /.(js|jsx|ts|tsx)$/,
include: [
path.resolve(__dirname, "stories")
],
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-react'],
plugins: ['@babel/plugin-transform-runtime']
},
},
{
test: /.(less)$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 2,
modules: {
// auto: /.module.\w+$/i,
localIdentName: "[local]--[hash:base64:5]",
exportLocalsConvention: "camelCase",
},
}
},
'less-loader'
],
}
],
},
externals: {
'react': 'React',
'react-dom': 'ReactDOM',
},
resolve: {
extensions: paths.moduleFileExtensions
.map(ext => `.${ext}`)
.filter(ext => useTypeScript || !ext.includes('ts')),
},
plugins: [
new webpack.DefinePlugin(env.stringified),
new CleanWebpackPlugin(),
],
};
发布组件文档
Storybook 文档发布教程地址:https://storybook.js.org/docs/react/sharing/publish-storybook#gatsby-focus-wrapper。