React 组件库搭建指南-开发调试与文档编写
MDX,文档生花。
概览
上一篇文章中进行了项目的初始化,同时编写了一个 组件,遗留了一个问题:
编写时完全无法进行预览调试
此处选择 docz 来辅助预览调试。
docz
基于 MDX
(Markdown + JSX),可以在 Markdown 中引入 React 组件,使得一边编写文档,一边预览调试成为了可能。而且得益于 React 组件生态,我们可以像编写应用一般编写文档,不仅仅是枯燥的文字。 docz
也内置了一些组件,比如 。
本节所有代码可在仓库 chapter-2 分支中获取。
安装 docz 以及自定义配置
yarn add docz --dev yarn add rimraf --dev # 清空目录的一个辅助库
增加 npm scripts
至 package.json
。
"scripts": { "dev": "docz dev", // 启动本地开发环境 "start": "npm run dev", // dev命令别名 "build:doc": "rimraf doc-site && docz build", // 后续会配置打包出来的文件目录名为doc-site,故每次build前删除 "preview:doc": "docz serve" // 预览文档站点 },
注意:本节所有操作都是针对站点应用。 打包
指代文档站点打包,而非组件库。
新建 doczrc.js
配置文件,并写入以下内容:
doczrc.js
export default { files: './components/**/*.{md,markdown,mdx}', // 识别的文件后缀 dest: 'doc-site', // 打包出来的文件目录名 title: 'happy-ui', // 站点标题 typescript: true, // 组件源文件是通过typescript开发,需要打开此选项 };
由于使用了 less
作为样式预处理器,故需要安装 less 插件。
yarn add less gatsby-plugin-less --dev
新建 gatsby-config.js
,并写入以下内容:
gatsby-config.js
module.exports = { plugins: ['gatsby-theme-docz', 'gatsby-plugin-less'], };
编写文档
新建 components/alert/index.mdx
,并写入以下内容:
--- name: Alert 警告提示 route: /Alert menu: 组件 --- import { Playground } from 'docz'; import Alert from './alert'; // 引入组件 import './style'; // 引入组件样式 # Alert 警告提示 警告提示,展现需要关注的信息。 ## 代码演示 ### 基本用法 这是一条警告提示 ## API | 属性 | 说明 | 类型 | 默认值 | | ---- | -------- | -------------------------------------------- | ------ | | kind | 警告类型 | 'info'/'positive'/'negative'/'warning'非必填 | 'info' |
执行脚本命令:
yarn start # or yarn dev
可以在 localhost:3000
看到如下页面 :
现在可以在 index.mdx
中愉快地进行文档编写和调试了!
倘若本文到了这里就结束(其实也可以结束了 (_^▽^_)
),那我只是官方文档的翻译复读机罢了,有兴趣的同学可以继续向下看。
优化文档编写
如果 代码演示
部分的 demo
较多(比如基本用法、高级用法以及各种用法等等),在组件复杂的情况下(毕竟 着实太简单了),会导致文档很长难以维护,你到底是在写文档呢还是在写代码呢?
那就抽离吧。
在 components/alert/
文件夹下新建 demo
文件夹,存放我们在编写文档时需要引用的 demo
。
components/alert/demo/1-demo-basic.tsx
import React from 'react'; import Alert from '../alert'; import '../style'; export default () => ;
components/alert/index.mdx
- import Alert from './alert'; // 引入组件 - import './style'; // 引入组件样式 + import BasicDemo from './demo/1-demo-basic'; ... - 这是一条警告提示 +
这样我们就将 demo 与文档进行了分隔。预览如下:
等等,你下面显示的那个 有点撩人,这里应该是给用户爸爸们
copy
的 demo
源码,你弄一个标签在这里,用户爸爸肯定不开心 :no_good:♀️。
然而 组件暂时无法支持上述形式的展示:自定义下方展示的代码,而非
内部的代码。相关讨论如下:
其实第一条 PR
已经解决了问题,但是被关闭了,无奈。
不过既然都能引入 React 组件了,在 MDX
的环境下自定义一个 Playground
组件又有何难呢,无非就是渲染组件(MDX 自带)和展示源码,简单开放的东西大家都是喜闻乐见的,就叫 HappyBox
吧。
优化代码展示
编写
组件
安装依赖:
yarn add react-use antd react-simple-code-editor prismjs react-copy-to-clipboard raw-loader --dev
- react-use – 2020 年了,当然要用
hooks
- antd – 使用一些辅助组件
- react-simple-code-editor – 代码展示区域
- prismjs – 代码高亮
- raw-loader – 将源码转成字符串
- react-copy-to-clipboard – 让用户爸爸们能够 copy demo 代码
这些依赖都是服务于文档站点应用,和组件库自身毫无关联。
最终效果如下:
根目录下新建 doc-comps
文件夹,存放文档中使用的一些工具组件,比如 。
doc-comps
├── happy-box │ ├── index.less │ └── index.tsx └── index.ts
components/doc-comps/happy-box/index.tsx
import React from 'react'; import Editor from 'react-simple-code-editor'; import CopyToClipboard from 'react-copy-to-clipboard'; import useToggle from 'react-use/esm/useToggle'; import { Divider, Typography, Icon, Tooltip, message } from 'antd'; import { highlight, languages } from 'prismjs/components/prism-core'; import 'prismjs/components/prism-clike'; import 'prismjs/components/prism-javascript'; import 'prismjs/components/prism-markup'; import './index.less'; require('prismjs/components/prism-jsx'); const { Text } = Typography; interface Props { code: string; title?: React.ReactNode; desc?: React.ReactNode; } export const HappyBox: React.FC = ({ code, title, desc, children }) => { const [isEditVisible, toggleEditVisible] = useToggle(false); return (); /* 代码展示区域 */ function renderEditor() { if (!isEditVisible) return null; return ({children} {title || '示例'} {renderEditor()}{desc || '暂无描述'}message.success('复制成功')}>{}} highlight={code => highlight(code, languages.jsx)} padding={10} className="container__editor" style={{ fontFamily: '"Fira code", "Fira Mono", monospace', fontSize: 14, }} />); } }; export default HappyBox;
相关配置变更
alias
新建 gatsby-node.js
,写入以下内容以开启 alias
:
const path = require('path'); exports.onCreateWebpackConfig = args => { args.actions.setWebpackConfig({ resolve: { modules: [path.resolve(__dirname, '../src'), 'node_modules'], alias: { 'happy-ui/lib': path.resolve(__dirname, '../components/'), }, }, }); };
antd
按需引入,安装依赖,并配置 gatsby-config.js
:
yarn add babel-plugin-import gatsby-plugin-import --dev
gatsby-config.js
module.exports = { plugins: [ 'gatsby-theme-docz', 'gatsby-plugin-less', { resolve: 'gatsby-plugin-import', options: { libraryName: 'antd', style: 'css', }, }, ], };
tsconfig.json
忽略 demo
以及 doc-comps
,避免组件库打包生成 types
时包含其中:
tsconfig.json
{ "compilerOptions": { "rootDir": "components", "baseUrl": "components", "target": "esnext", "module": "commonjs", "jsx": "react", "declaration": true, "outDir": "types", "strict": true, "moduleResolution": "node", "allowSyntheticDefaultImports": true, "esModuleInterop": true }, + "exclude": ["components/**/demo", "doc-comps"] }
改造相关文件
components/alert/demo/1-demo-basic.tsx
- import Alert from '../alert'; + import Alert from 'happy-ui/lib/alert'; - import '../style'; + import 'happy-ui/lib/alert/style';
components/alert/index.mdx
- import { Playground } from 'docz'; + import { HappyBox } from '../../doc-comps'; + import BasicDemoCode from '!raw-loader!./demo/1-demo-basic.tsx'; ... - - - + + +
其他
.eslintignore
+ doc-comps + demo
yarn start
卡住时尝试删除根目录 .docz
文件夹,而后重新执行命令。
更多详见 仓库 。
开发调试与文档编写结束,欢迎指点交流。
To be Continued…