本文共 5487 字,大约阅读时间需要 18 分钟。
Docz 可以与组件库代码混合使用,即在组件实现的同级别目录创建扩展名为 mdx 的组件同名文件;
如果你的项目是 lerna 项目,那么可以尝试另外一种方案,即:将组件库组件代码与docs 文档分离成两个子项目,这样每个子项目只关心各自的实现即可,下面我们把之前的案例改造成 docs 与 components 分离,源码可以到查看
其中
/packages/mjz-ui/
是组件库的实现/packages/docz/
是组件库文档
.├── lerna.json├── package.json├── packages│ ├── docs│ │ ├── __tests__│ │ ├── doczrc.js│ │ ├── gatsby-config.js│ │ ├── package.json│ │ ├── public│ │ │ └── avatar.png│ │ └── src│ │ ├── components│ │ ├── gatsby-theme-docz│ │ └── index.mdx│ └── mjz-ui│ ├── __tests__│ ├── package.json│ ├── rollup.config.js│ ├── src│ │ ├── components│ │ └── index.tsx│ └── tsconfig.json└── yarn.lock
组件需要输出给外部 通过
import {...} from '@mjz-test/mjz-ui'
来使用,这个时候就需要给源代码编译一下了,因为我们还使用了 less 因此这个案例我们暂时使用 rollup 简单的打包一个组件库(仅测试Docz用,真正的组件库打包方案会复杂一些)
- 给 mjz-ui 子项目安装依赖
yarn workspace @mjz-test/mjz-ui add @rollup/plugin-commonjs @rollup/plugin-node-resolve @rollup/plugin-typescript less postcss rollup-plugin-postcss rollup react react-dom typescript
- 安装完成后给 mjz-ui 子项目 添加 script
{ "scripts": { "dev": "rollup -c -w" }, "dependencies": { "@rollup/plugin-commonjs": "^17.0.0", "@rollup/plugin-node-resolve": "^11.0.1", "@rollup/plugin-typescript": "^8.1.0", "less": "^4.0.0", "postcss": "^8.2.1", "react": "^17.0.1", "react-dom": "^17.0.1", "rollup": "^2.35.1", "rollup-plugin-postcss": "^4.0.0", "typescript": "^4.1.3" }}
- 创建 rollup.config.js 配置文件
import typescript from '@rollup/plugin-typescript';import postcss from 'rollup-plugin-postcss';import commonjs from '@rollup/plugin-commonjs';import resolve from '@rollup/plugin-node-resolve';const config = { input: 'src/index.tsx', output: { dir: 'dist', format: 'esm', entryFileNames: 'index.js', intro: 'import "./index.css"' }, plugins: [ typescript(), postcss({ extensions: ['.less', '.css'], extract: true, }), commonjs(), // 模块加载 resolve({ browser: true, jsnext: true, main: true, }), ], external: ['react', 'react-dom'], watch: { include: 'src/**' }};export default config;
/** * 组件入口 * */ export {default as Alert} from './components/Alert'; export {default as Button} from './components/Button';
cd packages/mjz-ui && yarn dev
即可看到编译后的组件输出到 dist/index.js 中了{"module": "dist/index.js"}
可以通过
yarn lerna:create @mjz-test/docs
创建的这个组件库文档项目,创建后将其配置成如下结构
.├── __tests__├── doczrc.js # 从之前的 mjz-ui 迁移过来├── gatsby-config.js # 从之前的 mjz-ui 迁移过来├── package.json├── tsconfig.json # 从之前的 mjz-ui 复制过来├── public # 从之前的 mjz-ui 迁移过来│ └── avatar.png└── src ├── components # 只保留 mdx 文件 │ ├── Alert.mdx │ ├── Button.less # 如果 mdx 文件中要用到样式也可以配置 gatsby-plugin-xxx 后直接引入 │ └── Button.mdx ├── gatsby-theme-docz # 从之前的 mjz-ui 迁移过来 用来做文档定制化的 │ ├── customComponents │ │ ├── Menu.js │ │ └── index.js │ └── index.js └── index.mdx
- 因为组件库文档要使用 mjz-ui 中的组件,所以我们要给 docs 这个项目引用
@mjz-test/mjz-ui
这个包,这个包是我们正在开大的包,所以引用时要加当前的版本号
yarn workspace @mjz-test/docs add @mjz-test/mjz-ui@0.6.0 # 版本号需要去查一下 mjz-ui 的
实际上 lerna 会帮助我们把 @mjz-test/mjz-ui 这个包软连接到我们工作区的
/packages/mjz-ui
这里,每次这个包有改动也都会实时更新
- 组件库现在在 /packages/docs 项目中已经作为第三方 package 来使用了,因此我们需要改动对他的引用方式
# packages/docs/src/components/Alert.mdx---name: Alertroute: /alertmenu: Componentsweight: 1---import { Playground, Props } from 'docz';import {Alert, Button} from '@mjz-test/mjz-ui'; # 当做第三方包引用即可
除了引用方式改变外,其余与之前的使用习惯没有区别
以上就完成了 docs 与 components 的分离, 开发时
cd packages/mjz-ui && yarn dev
cd packages/docs && yarn dev
发生如上问题的原因是,我们的组件库在编译后,输出的不再 TS 模块,虽然其 Props 等 TS 类型声明不能很好的被另一个 Docz 项目的 组件识别,因此开发环境下还是得使用未编译的组件,我们需要按照如下配置
NOTICE: 1. 为什么不将 TS module 直接导出呢?package.json 设置 main 直接导出 ts 文件是可行的,但是作为开源组件库要给更多的人使用,没有办法规定用户一定要使用 TS,因此发布前一定会编译成 JS
NOTICE: 2. 还有中方案可以考虑在TS 编译成 JS 后,将其类型改为 prop-types 定义的类型,这样就可以识别了,(虽然会增加代码体积)
// 1. 首先确保在 docs 项目下也有一个 tsconfig.json 文件其内容与 @mjz-test/mjz-ui 一致,并且将 package/mjz-ui/ 目录作为其 include 之一,来保证可以正常的编译{ "include": ["src", "../mjz-ui/"] }// 2. 新增 gatsby-node.js 将 @mjz-test/mjz-ui 作为 docz 运行时的 webpack alias 而这个 alias 指向的是 @mjz-test/mjz-ui 的 /src 即 ts 源码,这样拿到的就是 TS 组件了(而不是编译后的JS 组件) // packages/docs/gatsby-node.jsconst path = require("path");exports.onCreateWebpackConfig = (args) => { args.actions.setWebpackConfig({ resolve: { alias: { "@mjz-test/mjz-ui": path.resolve(__dirname, "../../../packages/mjz-ui/src"), }, }, });};// 3. 调整 doczrc.js 配置,{ docgenConfig: { // 这个是一个 docz 未公开的一个配置 searchPatterns: ["../mjz-ui/**/*"], }, filterComponents: (files) => files.filter((filepath) => /\/[A-Z]\w*\.(js|jsx|ts|tsx)$/.test(filepath)), ignore: ["README.md", "../mjz-ui/node_modules"], // 排除掉 mjz-ui 中的一些不需要的}
- 再此开启组件库文档的开发环境
cd packages/docs && yarn dev
发现文档可以正常编译开发了
以上就完成了 docs 与 components 的分离, 开发时
cd packages/docs && yarn dev
yarn lerna:publish
mjz-ui 与 docs 会同步更新版本转载地址:http://ckvoz.baihongyu.com/