Docusaurus 出色的文档解决方案
目标 & 背景
在 内网 Package 管理 这篇文章中,有提到如何构建公司自有的框架,但由此就引发了一个新问题,那就是 文档
,也是困扰了我很久的一个心病,一个符合我想象的文档工具应当包含如下功能
- 支持版本管理
- 一个服务对应 N 套框架文档
- 要支持博客类型的文章
- 不需要引入其他编辑器软件
- 最好支持多语言,给未来一个可能
因此花了很多时间对比市面上现有的文档解决方案,最后 Docusaurus
胜出了
解决方案对比
在整个过程中,一共对比了 5 家解决方案,接下来挨个说明每家的优缺点
WiKi.js
这个解决方案非常适合单仓库使用,尤其是一些项目的策划文档、游戏攻略等,并且在 Web 上内置了编辑器,甚至可以直接使用 Draw.io 的绘图功能,在编辑过程上非常非常友好
但是很可惜,最重要的版本管理功能没有得到有效的官方支持
WriteSide
这个解决方案是 JetBrains 家的文档工具,整体是一个插件的形式,作用于 IntelliJ IDEA
中,在本文发布时,该插件仍然处于内测 beta 阶段
WriteSide 支持版本管理,但是部署过程相对麻烦,且仍然处于内测阶段。对于文档编写人员来说,必须下载对应的 IDE 才能开始,也是由于仍在开发对
Rider
的支持也并不完善
Mintlify
这个解决方案是我见到的最漂亮的文档了,下图为 tailwindcss
的文档首页
在官方文档中没有看到版本管理功能的介绍,但是 tailwindcss 的文档却有这个功能。不过最终没有选这个方案还是因为我们有 N 个框架,每个都部署一个服务的体验实在是太糟糕了
Hermes
这个解决方案是最近刚刚开源的,很多 feature 仍在开发中
Hermes 所有的文档目前都是存放在 Google Workspace 中,这个对于我们需要离线写文档的要求是非常大的挑战...
Docusaurus 介绍
Docusaurus 几乎完美解决了我们对文档的所有要求,在 github 上有 40K 个 star,唯一的遗憾是很多高级的 mdx
和 js
用法需要手敲很多内容,不过这个结合一些第三方应用的 snippets
功能可以显著改善
后文会以
Alfred
对snippets
做介绍,Windows 的话 需要自己研究啦
我们将后续所有的文档类型分为三个大类
分类 | 说明 |
---|---|
指南 | 一些公共文章,如内网如何配置、公司开发规范等 |
框架 | 每个 pacakge 对应一套自己版本管理的独立文档 |
博客 | 公司程序想要分享一些自己的技术文章 |
编辑文档的过程我们都在 VSCode 中进行,借助 VSCode 强大的插件市场,md
和 mdx
文件的高亮也自然不在话下,而 Docusaurus 强大的地方在支持 hotrealod 功能,你可以一边写文档,一边实时在 web 上看到所有变化
正常的编写流程,需要先开启服务,Docusaurus 会自动在
localhost:3000
开启一个本地服务,保存文件时,web 就会实时刷新
npm run start
最后在 git hook 的 server 端,配好 CI/CD
流程,当有人更新文档时,运行如下指令,公司内网的文档服务就可以实时发布了
npm run build
Docusaurus 的整体方案非常舒服,而且也完成了本身文档如何使用的自举,文档非常详细,也支持中文,如果你们也需要使用,建议完整阅读所有文档
Docusaurus 常用语法
下方所提到的内容均支持任意程度的嵌套,可以非常灵活
选项卡 Tabs
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
<Tabs>
<TabItem value="apple" label="苹果" default>
这是个苹果
</TabItem>
<TabItem value="orange" label="橙子">
这是个橙子
</TabItem>
<TabItem value="banana" label="香蕉">
这是个香蕉
</TabItem>
</Tabs>
注意此处和官方有些不同,TabItem
前面没有任何空格,在一些复杂的嵌套环境下,如果没有删除空行会导致渲染失败
折叠 Details
<details>
<summary>点击查看更多</summary>
我是隐藏内容
</details>
默认情况下是折叠的,点击后才会展开
告示
:::note
Some **content** with _Markdown_ `syntax`. 看看[这个 `api`](#)。
:::
:::tip
Some **content** with _Markdown_ `syntax`. 看看[这个 `api`](#)。
:::
:::info
Some **content** with _Markdown_ `syntax`. 看看[这个 `api`](#)。
:::
:::caution
Some **content** with _Markdown_ `syntax`. 看看[这个 `api`](#)。
:::
:::danger
Some **content** with _Markdown_ `syntax`. 看看[这个 `api`](#)。
:::
这个功能在写文档时也非常有用,比如你希望强调这里必须要这么做时,一个 danger
就可以非常抢眼
Alfred Snippets 配置
看到这里你会发现尤其是 Tabs
和 Details
要手敲非常多的内容,当文档需要写很多类似内容时,人都麻了,借助 Alfred 的功能,可以将这个过程减少到一个单词,剩下的 Alfred 会替你自动补全
这里我们以 Details
举例,首先 Docs
这个组默认的前缀为 !
,因此有如下配置
当你在任意处敲出关键字后,就会自动替换为 Snippet
中的内容,而中间的 {cursor}
代表替换后,光标的默认位置在哪里
// 输入
!details
// 自动替换的结果
<details>
<summary>点击查看更多</summary>
{cursor}
</details>
最后
Decusaurus 这个文档工具越用越惊喜,不愧是拥有 40k star 的仓库,作为框架的最后一块拼图也终于补齐了。写文档对于程序来说,是一个非常好的习惯,不管是记录过程的博客,还是框架的说明文档,都能让程序更贴近业务
尤其是底层的框架开发,如果研发人员对业务不敏感,最后的产出一定是一坨屎(这个是血和泪的教训)