文档即代码(Docs as Code)把技术文档当作源代码一样对待:用 Git 做版本控制、用 Markdown 写内容、用 CI 自动构建与发布。它能根治文档与代码脱节、Review 缺失、过期没人敢信的老毛病,让文档像代码一样可审查、可追溯、可回滚。
一、为什么传统文档总是”写完就过期”
大多数团队的文档活在三类地方:项目根目录的 doc/ 文件夹、Confluence 或语雀这类 Wiki、或者干脆散落在即时通讯群里。它们的共同问题是——文档和代码是两套系统。代码改了,文档没人同步;新人想提个文档修改,发现根本没有 PR 这种概念;半年后文档和现实差了十万八千里,谁都不敢信,最后变成”文档仅供参考”。
文档腐烂的代价往往是隐性的:一个新同学想接手某个模块,翻遍仓库找不到最新设计文档,只能在群里问老人;老人的回答又散落在聊天记录里。等他终于拼凑出全貌,可能已经踩了三个坑。更糟的是,当文档和代码分属两套系统,没有人能为”文档是否还正确”负责——代码至少有测试兜底,文档没有。文档即代码要解决的,正是这个”双轨制”问题:让文档进入和代码相同的生命周期。
二、文档即代码的核心四件套
2.1 纯文本写作:Markdown / AsciiDoc / reStructuredText
放弃富文本编辑器,改用纯文本标记语言。纯文本意味着可以用 Git 做行级 diff、可以做 grep 搜索、可以被 CI 校验。Markdown 上手最快,AsciiDoc 和 reStructuredText(RST)则适合需要交叉引用、多版本、复杂排版的大型文档工程。
2.2 版本控制:Git 即真相源
所有文档放进 Git 仓库,和代码同库或相邻仓库。每次修改都是一个 commit,可以 Review、可以 blame、可以回滚到任意历史版本。文档的”最新正确状态”不再是某个人脑子里的东西,而是 main 分支上的内容。
2.3 自动化:CI 构建与预览
提交文档后,由 CI(例如 GitHub Actions 搭建的流水线)自动做拼写检查、死链检测、构建预览站。提交 PR 时自动生成预览链接,reviewer 不用本地搭环境就能看到渲染效果。
2.4 发布:静态站点
用 MkDocs、Sphinx、Docusaurus 等工具把 Markdown 构建成静态站点,合并到 main 即自动部署上线。整个过程没有人工拷贝粘贴。
三、最小可用工作流:从零搭起来
一个典型的仓库结构长这样:
docs-repo/
├── docs/
│ ├── index.md
│ ├── quickstart.md
│ └── api/
│ └── reference.md
├── mkdocs.yml # 站点配置:导航、主题
└── .github/
└── workflows/
└── docs.yml # CI:构建 + 预览 + 部署
CI 工作流负责三件事——构建、预览、部署:
name: docs
on:
push:
branches: [main]
pull_request:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install mkdocs-material
- run: mkdocs build --strict # 严格模式:有断链直接失败
- if: github.event_name == 'pull_request'
run: mkdocs gh-deploy --no-history # 生成 PR 预览站
推荐用 VS Code 配合 Markdown 插件 写作,实时预览、一键插入代码块,比任何在线富文本编辑器都顺手。
四、它和”代码生成文档”是两回事
很多人会混淆两个概念。像 Swagger / SpringDoc 自动生成 API 文档 属于”代码生成文档”——文档内容从代码注解里抽出来,代码是源、文档是副产品。而文档即代码的源是人写的中文 Markdown,构建工具只是把它渲染成网页。两者并不冲突,反而互补:API 参考用代码生成保证不落后于接口,设计文档、教程、决策记录用手写 Markdown 走文档即代码流程。一个成熟团队往往两条线并行,而不是二选一。
五、团队落地清单
别一上来就追求完美,按成熟度分阶段推进:
| 阶段 | 目标 | 关键动作 |
|---|---|---|
| 入门 | 文档进 Git | 把散落各处的文档迁到仓库,统一用 Markdown |
| 进阶 | 有 Review | 文档变更走 PR + 至少一人审批,禁直接推 main |
| 成熟 | 自动化 | CI 做死链与拼写校验,PR 自动出预览站 |
| 标杆 | 可观测 | 统计文档访问量与反馈,驱动持续更新 |
六、落地时最容易踩的坑
坑一:把全部历史文档一次性迁进来。 老文档又臭又长,全量迁移会劝退团队。先迁活跃项目,立标杆再推广。
坑二:只有构建没有校验。 没有 --strict 这类硬约束,断链和过期图表会悄悄积累。让 CI 红起来才有威慑力。
坑三:文档仓库和代码仓库彻底隔离。 理想情况是文档和对应代码放在同一 monorepo 或相邻仓库,改代码时顺手改文档,而不是跨系统记忆。
坑四:把文档权限锁死在个人账号。 文档进了某人的私人仓库或网盘,人一离职就成死链。文档即代码的前提是”组织资产”,用团队或组织仓库加只读归档,比个人空间稳妥得多。
七、附:一个可直接抄的 mkdocs.yml
光说不练没感觉,下面这份配置是 MkDocs Material 的精简可用版,复制即可跑:
site_name: 团队文档
theme:
name: material
features:
- navigation.sections
- content.code.copy
nav:
- 首页: index.md
- 快速开始: quickstart.md
- API: api/reference.md
markdown_extensions:
- admonition # 支持 !!! note 提示框
- pymdownx.superfences
把这份配置和前面的目录结构放在一起,mkdocs build 就能产出一套带搜索、带侧边导航的静态文档站。admonition 扩展让你用 !!! note 写”注意 / 警告”提示框,比纯加粗醒目得多;content.code.copy 则给每个代码块加一键复制按钮,读者体验直接拉满。如果你的文档长期只有一个人维护,这套配置也能让你在换电脑、换环境时零成本恢复工作状态—— clone 下来就能本地 mkdocs serve 预览,不必再四处追问”最新的文档到底在哪个网盘”。
八、小结
文档即代码不是什么新框架,而是一套”把文档当资产而非负担”的工程纪律。它用 Git 解决版本、用 CI 解决质量、用静态站点解决发布,最终让文档和代码在同一节奏上演进。当你下次又想新建一个在线文档空间时,不妨先想想:这篇文档,能不能直接进 Git?如果答案是能,那就别犹豫,开个仓库吧。




