1.背景
- 多个系统共用一个组件库
- 组件库目前难以管理,组件的改动会同时影响多个系统中组件的展示和交互,开发人员对组件改动带来的影响难以把控
- 项目中组件库使用频繁,但是查阅组件API繁琐,需要翻阅组件代码
- 无法直观全面地了解每个组件具备的功能,对新人学习成本较高,组件新增功能也无法快速让组内其他人了解
2. bisheng介绍
bisheng 是一个把 Markdown 转为 React 单页网站的工具,可以支持简单的个人博客,可以快速构建及管理项目接口文档, 通过插件扩展后可支持组件demo展示及更加复杂的内容。
组件库中使用bisheng,可以基本解决背景中所述问题。
ant-design文档就是基于bisheng实现的。
参考使用项目代码: ant-design
3.安装
npm install --save-dev bisheng
必须依赖
- bisheng
其他非必须依赖(网站相关, 根据需求自行安装)
- bisheng-plugin-description //用于把MarkDown的描述部分提取出来
- bisheng-plugin-toc //用于自动生成文章的 TOC(Table of Content)
- bisheng-plugin-react //在 Markdown 中写 React 代码,会被转为 React Element
- bisheng-plugin-antd
- ...
4.配置解析
4.1. package.json中添加命令:
"site": "cross-env ENV=production bisheng build -c ./site/bisheng.config.js",
"start": "rimraf _site && mkdir _site && cross-env NODE_ENV=development bisheng start -c ./site/bisheng.config.js"
4.2. 在项目目录下创建site文件夹
在site目录下创建/bisheng.config.js,配置如下
const path = require('path');
/**
* bisheng start读取
*/
module.exports = {
theme: './site/theme', //设置网站的主题的目录
port: 8881,
hash: true,
exclude: '',//排除某些文件,bisheng将不会解析匹配排除的文件
source: {//找到这个source下的所有的markdown文件并返回一个数组,需要被展示的markdown文件必须配置在source中
components: './components' //组件所在文件夹路径
},
htmlTemplate: './site/theme/static/template.html', // 页面模板
themeConfig: { //主题配置
categoryOrder: {},//category显示顺序
typeOrder: {}//type显示顺序
},
filePathMapper(filePath) {}, //文件路径转换方法
doraConfig: {
verbose: true,
},
lessConfig: {
javascriptEnabled: true,
},
webpackConfig(config) {
//文档中可以使用的别名
config.resolve.alias = {
site: path.join(process.cwd(), 'site'),
'components':path.join(process.cwd(), 'components')
};
config.externals = {
'react-router-dom': 'ReactRouterDOM'
};
config.module.rules.push({
test: /\.mjs$/,
include: /node_modules/,
type: 'javascript/auto',
});
return config;
},
devServerConfig: {
public: process.env.DEV_HOST || 'localhost',
disableHostCheck: !!process.env.DEV_HOST,
},
};
4.3. 在site目录下创建theme相关文件
theme
├── index.js //页面配置文件
├── static
└── template.html //页面模板
└── template //页面内容
├── index.js
├── NotFound
└ ...
4.4. 修改theme/index.js 配置
const path = require('path');
const homeTmpl = './template/index';
module.exports = {
lazyLoad(nodePath, nodeValue) {
if (typeof nodeValue === 'string') {
return true;
}
return nodePath.endsWith('/demo');
},
//匹配文件名配置分块md数据,并传递给模板。
pick: {
components(markdownData) {
const { filename } = markdownData.meta;
if (!/^components/.test(filename) || /[/\\]demo$/.test(path.dirname(filename))) {
return null;
}
return {
meta: markdownData.meta,
};
}
},
routes: { //页面路由配置
path: '/',
component: homeTmpl,
indexRoute: { component: homeTmpl },
childRoutes: [],//{path: '', component: ...}
},
};
4.5. 修改theme/static/template.html
<!DOCTYPE html>
<html {{ htmlAttributes | safe }}>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{% if title %}{{ title | safe }}{% else %}{% endif %}</title>
{% if meta %}{{ meta | safe }}{% endif %}
{% for cssFile in manifest["css"] %}
<link rel="stylesheet" type="text/css" href="{{ root }}{{ cssFile }}" />
{% endfor %}
<link rel="stylesheet/less" type="text/css" href="{{ root }}color.less" />
</head>
<body>
<div id="react-content">
{{ content | safe }}
</div>
{% for jsFile in manifest["js"] %}<script src="{{ root }}{{ jsFile }}"></script>
{% endfor %}
</body>
</html>
上述配置完成后,运行 npm start 命令,本地环境即可正常运行。
页面接收的props对象中包含已经处理过的所有md文件数据,根据props中的相关数据和方法自定义自己的个性化页面既可。