Docusaurus 出色的文档解决方案

目标 & 背景

内网 Package 管理 这篇文章中,有提到如何构建公司自有的框架,但由此就引发了一个新问题,那就是 文档,也是困扰了我很久的一个心病,一个符合我想象的文档工具应当包含如下功能

  1. 支持版本管理
  2. 一个服务对应 N 套框架文档
  3. 要支持博客类型的文章
  4. 不需要引入其他编辑器软件
  5. 最好支持多语言,给未来一个可能

因此花了很多时间对比市面上现有的文档解决方案,最后 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,唯一的遗憾是很多高级的 mdxjs 用法需要手敲很多内容,不过这个结合一些第三方应用的 snippets 功能可以显著改善

后文会以 Alfredsnippets 做介绍,Windows 的话 需要自己研究啦

我们将后续所有的文档类型分为三个大类

分类说明
指南一些公共文章,如内网如何配置、公司开发规范等
框架每个 pacakge 对应一套自己版本管理的独立文档
博客公司程序想要分享一些自己的技术文章

编辑文档的过程我们都在 VSCode 中进行,借助 VSCode 强大的插件市场,mdmdx 文件的高亮也自然不在话下,而 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 配置

看到这里你会发现尤其是 TabsDetails 要手敲非常多的内容,当文档需要写很多类似内容时,人都麻了,借助 Alfred 的功能,可以将这个过程减少到一个单词,剩下的 Alfred 会替你自动补全

这里我们以 Details 举例,首先 Docs 这个组默认的前缀为 !,因此有如下配置

当你在任意处敲出关键字后,就会自动替换为 Snippet 中的内容,而中间的 {cursor} 代表替换后,光标的默认位置在哪里

// 输入
!details

// 自动替换的结果
<details>
  <summary>点击查看更多</summary>

{cursor}
</details>

最后

Decusaurus 这个文档工具越用越惊喜,不愧是拥有 40k star 的仓库,作为框架的最后一块拼图也终于补齐了。写文档对于程序来说,是一个非常好的习惯,不管是记录过程的博客,还是框架的说明文档,都能让程序更贴近业务

尤其是底层的框架开发,如果研发人员对业务不敏感,最后的产出一定是一坨屎(这个是血和泪的教训)

参考

  1. Decusaurus: https://docusaurus.io/zh-CN/docs/installation
  2. WiKi.js: https://js.wiki/
  3. WriteSide: https://plugins.jetbrains.com/plugin/20158-writerside/docs/project-structure.html
  4. Mintlify: https://mintlify.com/docs/components/accordion
  5. Hermes: https://github.com/hashicorp-forge/hermes