一个文档工具差点让我通宵,但值了

编译通过了吗
2025-12-23 04:00
阅读 210

上周五晚上十点半,我合上 MacBook,长舒一口气——终于把团队的前端文档体系搭好了。窗外北京的晚风裹着初夏的燥热吹进来,地铁末班车早就没了,只能打车回昌平。这事儿得从我们实验室最近接的一个校企合作项目说起。

我是北邮软件工程研二的学生,平时在导师的横向项目组里搬砖。最近在做一个企业级数据可视化平台,前后端分离架构,我主要负责前端模块和一部分数据采集逻辑(对,就是写爬虫)。团队不大,五个同学加两个校外工程师,大家各自为战,代码风格不统一不说,最头疼的是——没人写文档!

产品经理甩过来一堆 Figma 设计稿,后端接口文档三天一变,测试同学天天在群里吼:“这个字段到底叫 user_id 还是 userId?” 我一度怀疑自己不是在做开发,而是在玩“大家来找茬”。

为什么文档工具成了救命稻草?

事情的转折点发生在双11前夕的一次线上事故。我们有个内部爬虫服务,用来抓取公开的行业数据,供前端展示趋势图。某天凌晨三点,运维大哥把我从梦中叫醒:“你那个 /api/scrape 接口挂了,返回 500,前端图表全白屏!”

我迷迷糊糊打开终端,发现是爬虫依赖的某个第三方库升级了 API,但我们没人知道这个接口是谁写的、怎么用、依赖哪些环境。最后花了两小时翻 Git 提交记录才定位到问题。那一刻我下定决心:必须搞一套自动化的文档工具链,不然迟早被产品经理和运维联合“制裁”

选型:Docusaurus vs VuePress vs 自研?

作为 Mac 党(Windows 只在我需要测 IE 兼容性时才会开机),我倾向用现代、轻量、支持 Markdown 的工具。调研了一圈,主要考虑三个方向:

  1. VuePress:团队里有人熟悉 Vue,上手快。
  2. Docusaurus:Meta 出品,支持多版本、国际化,React 生态友好。
  3. 自研脚本 + GitHub Pages:灵活,但维护成本高。

考虑到我们前端主框架是 React,且未来可能对接国际客户,最终选了 Docusaurus v3。它不仅能写静态文档,还能集成 API 自动生成、版本切换,甚至支持博客模式——正好可以把我们的技术方案沉淀下来。

npx create-docusaurus@latest my-docs classic --typescript
cd my-docs
npm start

三行命令跑起来,localhost:3000 上一个清爽的文档站点就出现了。那一刻我甚至有点感动:原来写文档也可以这么优雅。

实战:把爬虫接口文档化

我们的爬虫服务是用 Python FastAPI 写的,但前端需要知道每个接口的请求参数、返回结构、错误码。传统做法是手写 Swagger,但更新不及时,而且和前端文档割裂。

我灵机一动:能不能让前端文档站直接“吃掉”后端的 OpenAPI spec?

Docusaurus 有个插件叫 @docusaurus/plugin-content-docs,配合 redocswagger-ui 就能嵌入交互式 API 文档。但我更进一步——用脚本每天凌晨自动拉取后端的 /openapi.json,转换成 Markdown 表格,放进 Docusaurus 的 docs 目录。

关键脚本如下(简化版):

// scripts/generate-api-docs.ts
import { writeFileSync } from 'fs';
import fetch from 'node-fetch';

async function fetchOpenAPI() {
  const res = await fetch('http://internal-api.example.com/openapi.json');
  const spec = await res.json();
  
  let md = '# 爬虫服务 API 文档\n\n';
  for (const [path, methods] of Object.entries(spec.paths)) {
    for (const [method, details] of Object.entries(methods)) {
      md += `## ${method.toUpperCase()} ${path}\n\n`;
      md += `${details.summary || ''}\n\n`;
      
      // 生成请求参数表格
      if (details.parameters) {
        md += '| 参数 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n';
        for (const param of details.parameters) {
          md += `| \`${param.name}\` | \`${param.schema?.type}\` | ${param.required ? '是' : '否'} | ${param.description || ''} |\n`;
        }
        md += '\n';
      }
    }
  }
  
  writeFileSync('docs/api/crawler.md', md);
  console.log('✅ API 文档已更新');
}

fetchOpenAPI().catch(console.error);

然后在 package.json 里加个定时任务:

{
  "scripts": {
    "docs:api": "tsx scripts/generate-api-docs.ts",
    "docs:build": "npm run docs:api && docusaurus build"
  }
}

现在,只要后端改了接口,第二天早上我们的文档站就会自动同步。测试同学再也不用问字段名了——直接看文档就行。

前端组件文档也不放过

光有 API 不够,我们的 React 组件库也得文档化。以前都是靠 Storybook,但部署麻烦,还得单独维护。

Docusaurus 支持 MDX(Markdown + JSX),这意味着我可以在文档里直接写 React 组件示例:

---
title: DataChart 组件
---

import DataChart from '@site/src/components/DataChart';

## 基础用法

展示行业趋势数据:

<DataChart data={sampleTrendData} height={300} />

## Props 说明

| 属性 | 类型 | 默认值 | 描述 |
|------|------|--------|------|
| data | `Array<{x: string, y: number}>` | - | 图表数据源 |
| height | `number` | 200 | 容器高度 |

本地开发时,改一行代码,文档里的示例实时刷新。所见即所得,简直不要太爽。关键是,所有文档和代码都在同一个 Git 仓库,PR 里顺手更新文档成了团队新默契。

踩过的坑和血泪教训

当然,过程没那么顺利。分享几个踩过的坑:

  1. Mac 和 Windows 路径问题
    我们有个同学用 Windows 测试,结果 scripts/generate-api-docs.ts 里的路径分隔符炸了。后来统一用 path.join() 解决。

  2. Docusaurus 构建慢
    随着文档增多,docusaurus build 要 2 分钟。我加了缓存和增量构建,还配置了 CI/CD 只在 main 分支 push 时才全量构建。

  3. 权限控制缺失
    内部 API 文档不能公开。我们临时方案是部署到内网 Nginx,加 basic auth。长期打算接入公司 LDAP。

  4. 产品经理又改需求了
    上周 PM 说:“能不能加个搜索功能,按业务场景查接口?” 好吧,Docusaurus 默认 Algolia 搜索要申请 key,我干脆自己用 Fuse.js 实现了个本地模糊搜索,50 行代码搞定。

效果:从混乱到有序

上线一个月,效果立竿见影:

  • 新成员入职,第一天就能看懂整个系统接口和组件用法
  • 跨团队协作时,直接甩文档链接,沟通效率翻倍
  • 最重要的是——再也没人在凌晨三点打电话问我接口字段了!

我们甚至把这套文档体系推广到了实验室其他项目组。导师看了都说:“你们这届研究生,有点东西。”

最后一点碎碎念

说实话,写文档这件事,在很多程序员眼里是“脏活累活”。但当你经历过一次线上事故、被测试追着问三天、或者看着实习生一脸迷茫地翻你半年前的代码时,就会明白:好的文档不是成本,而是杠杆

工具只是手段,核心是建立一种“文档即代码”的文化。我们现在的 PR 模板里强制要求:如果涉及接口或组件变更,必须附带文档更新。虽然一开始有人抱怨,但现在大家都习惯了——毕竟,谁不想少加班呢?

对了,如果你也在用 Docusaurus 或类似工具,欢迎交流!顺便求推荐好用的 API 文档 diff 工具,我想监控接口变更……(别问,问就是被后端兄弟坑怕了)


工具栈小结

用途 工具 备注
文档站点 Docusaurus v3 React + TS,支持 MDX
API 同步 自研 Node 脚本 每日 cron job
部署 GitHub Pages + 内网 Nginx 公开文档走 GH,内部走内网
搜索 Fuse.js 轻量级本地模糊搜索
版本管理 Git + Docusaurus 版本功能 对接产品迭代周期

写完这篇,地铁已经到西二旗了。明天还要改爬虫的反反爬策略,但至少,文档这块心病算是放下了。

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝