文档对于项目开发和维护、学习、重构、以及知识管理非常重要。
和写测试一样、大部分开发人员会觉得写文档是一件痛苦的事情,不过只有时间能够证明它的价值。比如对于人员流动比较大的公司,如果有规范的文档体系,转交工作就会变动非常轻松.
广义的文档不单指‘说明文件’本身,它有很多形式、来源和载体,可以描述一个知识、以及知识形成和迭代的过程。例如版本库代码提交记录、代码注释、决策和讨论记录、CHANGELOG、示例代码、规范、传统文档等等
1. 建立文档中心
我们公司是做IM的,所以之前我们优先使用’自己的’通讯工具来分享文档,这种方式有很大问题:
- 如果没有存档习惯(比如后端的API文档,因为由后端维护,一般不会主动去存档), 文档就可能丢失,而且通讯工具是不会永久保存你的文档的。当丢失文件就需要重新和文档维护者索要
- 糟糕的是文档维护者也是自己手动在本地存档的,这样导致的问题是: 如果工作转交,其他开发者需要花费一点时间来查找; 丢失了就真的没了
- 每一次文档更新要重新发一份, 这很麻烦,而且可能出现漏发的情况, 导致前后不一致.
- 关于知识的学习、以及有意义的讨论记录无法归档。
上面介绍的是一种非常原始的文档共享方式,很多小团队就是这么干的。
对于项目本身的文档建议放置在关联项目版本库里面,跟随项目代码进行迭代, 当我们在检索或跟踪文档的历史记录时,这种方式是最方便的。
然而很多应用是跨越多个团队的,每个团队都会有自己的文档输出(比如需求文档、系统设计文档、API文档、配置文档等等),而且通常也不会在一个版本库里。这时候文档就比较分散。所以一个统一的文档中心是很有必要。
我们公司现在选择的方案是Git+Markdown,也就是说所有的文档都放置在一个git版本库下。之前也考虑过商业的方案,譬如石墨文档、腾讯文档, 但管理层并不信任这些服务。
大概的git项目组织如下:
规范/ A应用/ 产品/ 设计/ API文档/ 测试/ 其他/ B应用/ 复制代码
Git版本库(例如Gitlab)有很多优势,例如历史记录跟踪、版本化、问题讨论(可以关联issue、或者提交)、多人协作、搜索、权限管理(针对不同的版本库或分组为不同人员设置权限)等等。
Git+Markdown可以满足开发者的大部分需求。但是Git最擅长的是处理纯文本文件、对于二进制是无能为力的,无法针对这些类型的文档进行在线预览和编辑。
所以Git+Markdown并不能满足多样化的文档处理需求,比如思维导图、图表、表格、PPT、白板等需求. 毕竟它不是专业的文档处理工具。所以对于产品、设计人员这些富文档需求场景,通常会按照传统方式或者更专业的工具对文档进行管理.
2. 文档格式
毫无疑问,对于开发者来说,Markdown是最适合的、最通用的文档格式。支持版本库在线预览和变更历史跟踪。
下面这些工具可以提高Markdown的开发效率:
- 可视化编辑器
- markdownlint: 编码检查器
- 扩展(Visual Studio Code):
- Markdown All in One: All you need to write Markdown (keyboard shortcuts, table of contents, auto preview and more)
- Markdown TOC: markdown 目录生成,我最常用的markdown插件
图表绘制工具:
- drawio 基于Web的图表绘制工具、也有离线客户端
- KeyNote/PPT 临时绘图也不错
3. 定义文档的模板
关于如何写好文档,很难通过标准或规范来进行约束,因为它的主观性比较强, 好的文档取决于编辑者的逻辑总结能力、表达能力、以及有没有站在读者的角度去思考问题。
所以大部分情况下,我们可以为不同类型的文档提供一个模板,通过模板来说明一个文档需要包含哪些内容, 对文档的编写者进行引导.
例如一个API文档可能需要这些内容:
接口的索引
- 接口的版本、变更记录
- 用法和整体描述, 认证鉴权等等
- 描述具体的接口
- 功能说明
- 方法名称或者URI
- 参数和返回值定义
- 调用示例
- 注意事项等等
具体规范内容因团队而异,这里点到为止.
扩展:
- 中文技术文档的写作规范
-
4. 讨论即文档
一般情况下,对于一个开源项目来说除了官方文档,Issues也是一个很重要的信息来源。在Issue中我们可以获取其他开发者遇到的问题和解决方案、给官方反馈/投票、关注官方的最新动态、和其他开发者头脑风暴唇枪舌战等等。
所以相对于使用IM,笔者更推荐Issue这种沟通模式,因为它方便归档组织,索引和查找。而IM上的讨论就像流水一样,一去不复返。
当然两种工具的适用场景不一样,你拿IM的使用方式来使用Issue,Issue就会变得很水。Issue适合做有意义的、目的明确的讨论。 所以要谴责一下在Github Issue上灌水的开发者。
关于Issue有很多妙用,推荐阅读这篇文章<如何使用 Issue 管理软件项目?>
现在很多开源项目都引入了RFC(请求意见稿)流程(参考React采用新的RFC流程, 以及Vue 最黑暗的一天), 这让开发者有‘翻身农奴、当家做主’的感觉,任何人都可以参与到一个开源项目重大事件的决策之中。每个RFC会说明决策的动机、详细设计、优缺点。除了官方文档之外,这些RFC是很有价值的学习资料。
我觉得如果不涉及机密,团队应该要让更多人参与到项目的设计和决策中,对于新手可以学到很多东西,而对于发起者也可能有考虑不周的情况。
那对于企业应用开发, Issue有用吗?
当然有用, 比如我们可以将这类话题从IM转移到Issue: 设计方案
- 决策/建议
- 新功能、新技术引入
- 重构
- 性能优化
- 规范
- 问题讨论
- 重大事件
- 计划或进度跟踪
- …
5. 注释即文档
必要和适量的注释对阅读源代码的人来说就是一个路牌, 可以少走很多弯路.
关于注释的一些准则,<阿里巴巴Java开发手册>总结得非常好, 推荐基于这个来建立注释规范。另外通过ESlint是可以对注释进行一定程度的规范。
6. 代码即文档
现在有很多种工具支持从代码中解析和生成文档, 这可以给开发者简化很多文档维护的工作。
举个例子,我们经常会遇到修改了代码,但是文档忘记同步的情况。通过‘代码即文档’的方式至少可以保持文档和代码同步更新;另外很多工具会分析代码的数据类型,自动帮我们生成参数和返回值定义,这也可以减少很多文档编写工作以及出错率。
比如可以通过下面注释方式来生成组件文档
import * as React from 'react';
import { Component } from 'react'; /** * Props注释 */
export interface ColumnProps extends React.HTMLAttributes<any> {
/** prop1 description */
prop1?: string;
/** prop2 description */
prop2: number;
/** prop3 description */
prop3: () => void;
/** prop4 description */
prop4: 'option1' | 'option2' | 'option3'; }
/** * 对组件进行注释 */
export class Column extends Component<ColumnProps, {}> {
render() {
return <div>Column</div>;
}
}
复制代码
相关的工具有:
- API文档
- 后端接口文档
- 组件文档
- StoryBook 通用的组件开发、测试、文档工具
- React
- Vue
- vue-styleguidist
- 有更好的工具请评论告诉我