用 VuePress 开发组件库文档踩坑总结

前阵子给公司业务写了一个 Vue 组件,想着可能会在很多项目里复用,于是就将它封装成的 npm 包。

处理完后觉得应该准备一份在线文档,本打算继续用 docsify 来写文档(因为用过熟悉),但考虑需要在文档里增加组件的演示代码,最好能在 markdown 文件里直接写 vue 代码,并且还要支持 ElementUI ,因为我的组件是基于 ElementUI 开发的。

做了一系列的调研,最后选择使用 VuePress 做为文档开发框架。

VuePress 官方文档挺详细,上手几乎没什么难度,说干就干,在我的 npm 包项目里新建一个 docs/ 目录,然后执行 yarn add -D vuepress 安装,很快文档就跑起来了。

引入 ElementUI 报错

接着要引入 ElementUI ,在 docs/.vuepress/enhanceApp.js 里写入:

1
2
3
4
5
6
7
8
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

export default ({
Vue
}) => {
Vue.use(ElementUI)
}

结果运行报错,提示 Cannot find module 'core-js/library/xxx' when import element-ui ,查了下 issues ,是因为 core-js 这个包版本导致的。

因为我的项目是通过 Vue-cli 创建的,默认使用的 core-js 是 3.x 的版本,而 VuePress 需要使用 2.x 的版本才能正常运行,卸载 3.x 安装 2.x 又会导致我的项目无法正常运行,所以最后我的解决办法就是项目归项目,文档归文档。

引入自己的组件打包报错

接着引入我自己开发的组件,就像这样:

1
2
3
4
5
6
7
8
9
10
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import SkuForm from 'vue-sku-form'

export default ({
Vue // VuePress 正在使用的 Vue 构造函数
}) => {
Vue.use(ElementUI)
Vue.use(SkuForm)
}

并且在 markdown 里愉快的写着示例,一切都很正常,当我写了2,3个例子后,想打包预览下最终效果,结果一执行 vuepress build docs 就会报错了,提示 document is not defined

也是查了资料才了解到原因,因为 VuePress 在打包时是通过 Node.js 服务端渲染,因为 Node.js 里没有 document 对象,所以就报错了。最终解决办法如下:

1
2
3
4
5
6
7
8
9
10
11
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

export default ({
Vue // VuePress 正在使用的 Vue 构造函数
}) => {
Vue.use(ElementUI)
import('vue-sku-form').then(function (m) {
Vue.use(m.default)
})
}

使用 vuepress-plugin-demo-container 插件

至此,基本没再遇到什么坑了,唯一不够爽的就是,虽然 VuePress 支持在 markdown 里直接写 vue 代码,但因为我这是组件库的文档,也就是文档里不光要有示例,还得展示示例代码,也就是说一份代码得写两遍,一份用来展示示例,一份用来展示代码,如果要修改,也得两份代码同时修改,就像下面这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
## 示例

<template>
<SkuForm />
</template>

## 示例代码

```html
<template>
<SkuForm />
</template>
`` ` ← 文档中会删除左侧空格

最想能想到的解决方案是用 VuePress 提供的 <<< @/filepath ,就像这样:

1
2
3
4
5
6
7
8
9
## 示例

<SkuFormDemo />

## 示例代码

```html
<<< @/docs/.vuepress/components/sku-form-demo.vue
`` ` ← 文档中会删除左侧空格

但也还是有弊端,因为文件变多了,原先文档和示例都写在一个 markdown 文件里,现在需要将示例部分单独存放。

最后寻寻觅觅找到了 vuepress-plugin-demo-container ,效果很不错,风格和 ElementUI 的文档很像,并且最重要的是,示例和示例代码不用写两遍,而且可以直接在 markdown 中编写,一下子解决了上面说的两个痛点。

部署到 github pages

需要注意,github pages 指定的目录只能是 / 根目录或者 /docs 目录,而 VuePress 的源文件目录就是 /docs ,所以需要改个名字,然后在 .vuepress/config.js 里设置 dest: 'docs' ,将打包目录设置为 /docs

参考