前言
由于业务快速发展,业务组件库也在快速迭代。当组件Props等发生变化时,开发人员需要额外的消耗一定精力去保持代码和文档的统一。
此时,我们就可以利用TypeScript的静态类型检查与代码提示能力,通过自动生成文档工具,来增强开发的生产力,解放双手,提高工作效率。
背景
团队内部组件库文档年久失修,组件规范不统一,导致对很多组件的修改是牵一发而动全身,痛定思痛,于是经过小组商议后决定从组件文档着手,逐 步统一业务组件风格规范和组件文档。
调研
通过调研以及过往经验,发现市面上有几款插件可供选择,分别是Docz、StoryBook、dumi、react-docgen、react-docgen-typescript,根据与目前项目匹配度最终dumi和react-docgen-typescript进入了决赛圈,最终根据灵活的和对目前的项目整体的副作用,选择了react-docgen-typescript和react-styleguidist配合生成文档。
dumi
dumi,中文发音嘟米,是一款为组件开发场景而生的文档工具,与 father 一起为开发者提供一站式的组件开发体验,father 负责构建,而 dumi 负责组件开发及组件文档生成。
- 特性
- 开箱即用,将注意力集中在组件开发和文档编写上
- 基于 TypeScript 类型定义,自动生成组件 API
- 丰富的 Markdown 扩展,不止于渲染组件 demo
- 支持移动端组件库研发,内置移动端高清渲染方案
- 一行命令将组件资产数据化,与下游生产力工具串联
react-docgen
- 来自Facebook开源
- 基于Babel解析源码,对propTypes支持良好
- 虽然新版本支持 TypeScript,但从其它文件导入的类型信息无法被获取
- 不解析JSDoc部分,整个注释都作为描述部分,不过可以添加自己handler来补充解析
react-docgen-typescript
- 来自styleguidist开源,主要目标是服务TS React组件的API文档生成
- 基于TS解析源码,不支持propTypes,Props interface继承的类型都可以拿到
- 会读取JSDoc的@type、@default作为类型和默认值信息
业务实践阶段
安装
1 2 3 4 5 6 7 8 9 10 11
| "devDependencies": { "react-docgen-typescript": "^1.9.0", "react-styleguidist": "^7.3.7", }
"scripts": { "styleguide:dev": "cross-env STYLEGUIDE_ENV=development styleguidist server --config styleguide.config.js", "styleguide:build": "cross-env STYLEGUIDE_ENV=production styleguidist build --config styleguide.config.js" }
|
配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| const path = require('path'); const glob = require('glob'); const STYLEGUIDE_ENV = process.env.STYLEGUIDE_ENV
module.exports = { title: 'components', styleguideDir: 'dist', components: function () { return glob.sync(path.resolve(__dirname, 'src/componets/**/*.tsx')) .filter(function (module) { return /\/[A-Za-z]\w*\.tsx$/.test(module); }); }, resolver: require('react-docgen').resolver.findAllComponentDefinitions, propsParser: require('react-docgen-typescript').withDefaultConfig({ propFilter: { skipPropsWithoutDoc: true } }).parse, webpackConfig: Object.assign({}, STYLEGUIDE_ENV === 'production' ? require('./config/styleguide.webpack.config.prod') : require('./config/styleguide.webpack.config.dev')), dangerouslyUpdateWebpackConfig: function (config, env) { return { ...config, output: { ...config.output, filename: 'build/[name].bundle.js', chunkFilename: 'build/[name].js', }, } } };
|
组件内部配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| import React from 'react';
export interface ISelectProps {
dataSource: string[];
onChange?: (item: string) => void;
readOnly?: boolean;
size?: 'small' | 'medium' | 'large';
value?: string | number; }
class Select extends React.Component<ISelectProps> { static defaultProps = { readOnly: false, size: 'medium', };
render() { return <div>Test</div>; } } export default Select;
|
部署
执行build命令后,会生成dist文件,可根据自己的需求部署到指定位置。
总结
TypeScript给js带来了类型,做到静态类型检查和代码提示,经过上面一顿的折腾,把类型又用了一遍。整个过程中,我们已经拿到了组件中的所有想要拿到的数据并生成文档,不足的是子属性的类型并不能很好的显示,还需要后续完善,但是已经满足基础的需求。