文档工具踩坑记录

浮生若茶
2025-06-29 22:42
阅读 236

文档工具踩坑记录:一个开发工具工程师的血泪教训

文档工具踩坑记录:一个开发工具工程师的血泪教训

在过去的五年里,我一直在从事开发工具链相关的工作。从最开始搭建内部 CI/CD 流水线,到后来负责文档系统的建设和优化,我发现文档自动化生成工具虽然看起来“不是什么核心问题”,但往往成了团队协作中的一块隐形短板。

这篇文章我想和大家分享一下,我在构建公司文档系统过程中遇到的真实挑战、踩过的坑以及最终是如何走出泥潭的。希望能给正在做类似事情的你带来一些启发。

项目背景:为什么我们需要统一的文档系统?

我们团队早期使用的是各自维护的 Markdown 文档,随着人数增长和业务变复杂,文档越来越分散,更新不同步的问题频繁出现。特别是在新员工入职时,光是找一份完整的技术架构说明都要翻好几个仓库。

为了解决这个问题,我们决定引入一个统一的文档生成系统。目标很明确:

  • 自动化拉取代码仓库中的注释(主要是 Python 和 Java);
  • 构建一套可扩展的文档模板系统;
  • 支持多语言输出(Web、PDF、Markdown 等);
  • 最终部署在一个集中的内部文档平台,便于搜索和更新。

听起来是不是很完美?理想丰满,现实骨感。下面就是我们一路踩下来的大大小小的坑。


第一次尝试:用 Sphinx + reStructuredText 的失败教训

最初,我们选择了业界比较流行的 Sphinx 工具链,结合 reStructuredText(reST)格式来管理文档内容。Python 社区很多开源项目的官方文档都采用这个方案,技术成熟度看上去很高。

遇到的问题:

  1. 学习成本高
    reST 格式虽然功能强大,但语法门槛不低,尤其是对我们这些平时写 Markdown 写惯了的人。很多同事对 .. code-block:: python 这样的标记感到非常抵触。

  2. 中文支持差强人意
    默认情况下生成的 HTML 页面中文显示会有断句问题,排版也不够美观。我们在样式上做了大量定制,但每次升级 Sphinx 版本后样式又会崩。

  3. 自动提取 docstring 的问题
    我们希望从 Python 源码中自动生成 API 文档。Sphinx 提供了 sphinx.ext.autodoc 插件来实现这一功能,理论上没问题,但实际使用时发现:

    • 对于带有 type hint 的函数解析不够友好;
    • 多层嵌套模块时结构混乱;
    • 一些动态导入的模块直接报错,无法识别源码路径。
  4. 部署流程复杂
    每次构建文档都需要执行一堆命令,还要依赖特定版本的 Python 和 pip 包。在 CI 中跑的时候经常因为环境差异出错。更头疼的是部署到 Nginx 或内网服务器的过程也异常繁琐。

小插曲:

有次我晚上调试 Sphinx 的配置文件 conf.py 到凌晨两点,第二天早上开会领导看着我说:“你是去做文档的还是搞前端重构去了?” 🤪

最终结果:

尽管我们前期投入了不少精力,但最终因为文档写作体验差、自动化程度不足而被团队弃用。文档又回到了老路上——零散地写在 Wiki 上,没人愿意去更新。


第二轮:转向 MkDocs + Material 主题的尝试

有了第一轮的经验,我们在半年后重新启动了文档系统的建设工作。这次的目标更清晰:优先保证用户体验和易用性,其次才是功能丰富性。

我们选择了 MkDocs,结合 Material for MkDocs 这个主题。

优点:

  1. Markdown 支持良好 所有文档都是纯 Markdown 编写,几乎没有学习成本。大家都可以轻松上手。

  2. 内置搜索 & 响应式设计 默认就带全文搜索、移动端适配等功能,非常适合我们这种快速迭代的团队。

  3. GitHub Pages 部署简单 能直接推到 GitHub Pages,配合 CI 自动部署,流程简洁。

技术选型思路:

工具 优势 劣势
Sphinx 功能强大,适合大型项目 学习曲线陡峭,部署麻烦
Jekyll 支持 GitHub Pages 原生集成 配置复杂,Ruby 生态不亲和
MkDocs 易用性强,部署便捷 插件生态不如 Sphinx 成熟

我们权衡之后认为,现阶段易用性和部署效率更重要,后期再通过插件逐步增强功能。


接入自动文档生成机制

接下来要解决的核心问题是“如何从源码中提取文档并自动合并进 MkDocs 项目”。

我们采用了一套混合式方案:

  1. Python 项目使用 pydoc-markdown 自动生成 Markdown 注释文档
    我们写了一个脚本,在 CI 阶段自动将所有模块生成对应的 .md 文件,并放到 docs/api 下。

    # 安装 pydoc-markdown
    pip install pydoc-markdown
    
    # 生成对应模块的文档
    pydocmd simple mypackage.submodule > docs/api/submodule.md
    

    我们还写了个简单的 wrapper 脚本批量处理多个模块。

  2. Java 项目使用 Javadoc + Swagger UI 展示 REST 接口文档
    对于 Java 微服务,我们使用 javadoc 生成 XML,然后转换成 Markdown,这部分我们借助了一个叫 doctum 的开源工具。

    java -jar doctum.jar generate --input src/main/java --output docs/java_api
    

    同时,接口文档部分我们用了 Springfox Swagger UI,在本地启动服务后截图导出,或者用自动化截图工具抓取。

  3. CI 集成
    我们把整个流程集成到了 GitHub Actions 中,每当代码合并进主分支时,就会自动触发文档构建与部署。

    name: Deploy Docs
    
    on:
      push:
        branches:
          - main
    
    jobs:
      build-deploy:
        runs-on: ubuntu-latest
        steps:
          - name: Checkout Code
            uses: actions/checkout@v3
    
          - name: Setup Python
            uses: actions/setup-python@v4
            with:
              python-version: '3.10'
    
          - name: Install Dependencies
            run: |
              pip install mkdocs mkdocs-material pydocmarkdown
    
          - name: Generate API Docs
            run: |
              ./scripts/generate_docs.sh
    
          - name: Build and Deploy
            run: |
              mkdocs gh-deploy --force
    

这样,只要主分支一更新,文档网站也会随之自动更新。


踩过的坑与解决方法总结

以下是我这几年在文档工具链上踩过的一些典型坑,以及相应的应对策略:

1. “API 文档总是漏掉新的类或方法”

  • 问题表现:某些新增加的类没有被自动扫描生成文档。
  • 根本原因:pydoc-markdown 只会处理导入后的符号,如果某个类没有被显式导入,它就不会出现在生成的文档中。
  • 解决方案:在包的 __init__.py 中添加必要的 from .xxx import xx 导入语句,确保符号能被正确识别。

2. “文档部署后 CSS 资源加载失败”

  • 问题表现:部署完的页面样式丢失,控制台报错资源找不到。
  • 排查过程:发现是因为我们修改了默认的 theme_dir 路径,导致静态资源路径不对。
  • 解决方案:不要轻易改动默认主题目录,如需定制建议用 extra_css 引入外部样式。

3. “CI 中文档构建失败,提示 ‘no module named xxx’”

  • 问题表现:CI 中运行生成脚本时报错说模块不存在。
  • 根本原因:文档构建阶段需要提前安装项目本身,否则模块无法导入。
  • 解决方案:在 CI 阶段先运行 pip install -e . 把当前项目作为开发包安装,避免模块找不到的问题。

4. “文档中出现了敏感信息”

  • 问题表现:有些测试代码里的 token、IP 地址等敏感信息也被自动提取进了文档。
  • 解决方式:我们在 CI 脚本中加入了文本过滤逻辑,在生成 .md 文件后进行关键字替换或删除处理。

5. “多人协作时文档冲突严重”

  • 问题表现:多个同学修改同一份文档时容易发生冲突。
  • 改进建议:我们拆分了文档结构,每个业务单元独立成章,尽量降低交叉编辑的概率;同时建立了文档贡献规范,要求每次提交前必须跑一遍 mkdocs serve 预览。

效果总结与收益

经过这套文档系统的持续演进,我们的团队现在达到了几个关键目标:

  • 新员工可以在一天内找到项目所需的所有资料,入职效率提升明显;
  • 接口文档与代码基本保持同步,接口调用方可以实时查阅;
  • 技术文档不再是“一次性工程”,而是成为日常开发的一部分;
  • CI/CD 流程中融入文档构建环节,提升了整体交付质量。

更重要的是,现在大家写文档不再是一件痛苦的事,反而成了一种习惯。


给开发者的几点经验分享

如果你也在考虑搭建自己的文档系统,以下几点建议或许能帮你少走弯路:

1. 别一开始就追求“大而全”

很多团队一开始就想把所有文档集中起来,结果陷入无休止的结构设计和模板定制。建议从小处入手,先解决最关键的问题——比如接口文档自动生成。

2. 文档编写体验比功能更重要

再强大的文档工具,如果用户嫌麻烦不想用,那就是失败的。优先选用简单直观的格式和流程,再考虑功能扩展。

3. CI 集成越早越好

让文档构建和部署像代码一样纳入 CI 流程,是保障文档持续更新的关键。我们现在的做法是:只要有代码变动,就必须有文档联动。

4. 加入审核机制

即使是自动化生成的内容,也要建立一定的审核机制。特别是涉及到对外公开的接口文档,最好设置一道人工复核流程。

5. 不要忽视搜索能力

文档数量一旦上去,搜索就成了刚需。Material 主题自带搜索非常好用,但如果文档规模更大,可能需要接入 Elasticsearch 或 Algolia。

6. 鼓励文化变革

文档从来不只是一个人的任务,它是一种团队文化。定期组织文档 Review,设立文档贡献奖励机制,都能有效推动文档建设。


结语

文档系统这件事,说到底不是技术难题,更多是一个“如何让人愿意写”的问题。我们经历了从 Sphinx 到 MkDocs 的转变,也从一次次踩坑中明白了:好的工具不仅要功能强大,更要体贴用户、降低门槛。

希望我的这些经历,能为你提供一些实用参考。也许某天你会想起这篇文章,当你面对“怎么文档又没人更新了”这个问题时,能稍微多一点信心,少走一段弯路。

最后送大家一句话,也是我在文档系统搭建过程中常常提醒自己的一句话:
“好文档 = 清晰表达 + 简洁流程 + 长期坚持。”

共勉之。

评论 0

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