从设计到管理,如何快速打造技术产品
本文将介绍一款技术产品的快速打造方法。
回顾自己近几年的工作经历,从最早 17 年在团队内部创建 [注1] ,到 19 年在开源社区参与 ICE 的由 1 到 10,再到 20 年由 0 到 1 创建了 。其间也曾在阿里前端委员会参与了 低代码引擎[注2] 早期的共建。这些经历都属于技术产品建设的范畴。
我见过一些有趣的想法和优秀的技术实现,但由于产品的定位问题,最终没有获得世俗意义上的成功;也经历过有非常系统性规划的项目,但由于分工和执行问题,最终错过了发展的时间窗口。服务好开发者确非易事,他们极其挑剔。把优秀的工程师们聚集在一起工作也并不容易,他们特立独行。
在如何服务好开发者群体、如何管理大型的多人协作项目问题上,自己不敢说有多少成功的经验,但也算是踩过不少的坑。当我再次面对技术产品化需求时,期望能系统性地梳理技术产品的建设方法,总结自己的经验为日后所用,也许对于其他同学来说也有些参考价值,因此写下了这篇文章。
在这篇文章当中,笔者将介绍「如何做」的方法论,不会讨论「为什么要做」的动机。由于笔者的工作经历主要以打造开源技术产品为主,因此在文章中又会主要以「开源技术产品」为例,但相信这些经验对于内部技术产品也是适用的。
一个技术产品的打造,涉及到设计产品、设计架构、管理项目、编写文档、开发官网、运营产品、管理需求和缺陷等多个环节。要把这几个环节都做好,才有可能成功。技术产品项目在不同的阶段又有不同的关注点,比方说前期更侧重设计,发布后更侧重运营,稳定期则更侧重需求管理和答疑,开源后则更侧重项目管理。
下面笔者将按照这几个环节来展开介绍相关的方法论和工具,并且会提供一些示例。
设计产品
打造技术产品的第一步是明确使用怎样的手段来解决目标用户的问题,即要「做什么」,其本质是完成用户产品的设计。
在此阶段可以进行一些输入,例如可以通过用户调研和市场调研的方式来得出:用户关注的问题当中,哪些是重要且紧急的?市面上有没有相关的产品来解决这些问题,当前解决得怎么样?由此可以明确,我们要打造的技术产品,定位是什么,提供哪些特性。
关于产品的特性,不妨思考:哪些功能是别人有我们也有的(We too)?哪些功能是别人有但我们可以做得更好的(We )?哪些功能又是我们独有的(We only)?
如果是图形界面类产品(例如开发者工具),则可以产出产品的交互稿:包含哪些功能模块,用户的使用流程是怎样的?如果是代码类产品(例如框架),则可以产出官网交互稿和文档大纲:设计产品官网的过程就是明确产品组织结构、核心能力及产品价值的过程,编写文档大纲的过程就是以客户视角审视产品用户体验的过程。对于基础库,还可以先明确对外 API 的设计:提供哪些属性、方法和事件?
总结一下,在产品设计环节主要交付的产物是:
市场调研报告,示例:《人工智能自动编程调研报告》
用户调研报告,示例:《淘系技术部前端外包现状调研报告》[注3]
产品交互稿,示例:《 研发工作台产品交互稿》
官网交互稿,示例:ICE 官网
文档大纲,示例:ICE 教程
设计架构
产品设计回答了「做什么」的问题,接下来要去考虑「怎么做」,其本质是完成软件架构的设计。
软件架构的重要性不言而喻,它是系统实现的蓝图、沟通协作的基础,决定了产品的质量。
关于如何设计一个好的架构以及怎么描述你的架构设计,有非常多成熟的方法论,这里就不再赘述了,笔者也在学习实践当中。在架构设计环节笔者的一个思路是:先做竞品调研,再做架构制图。
做竞品调研,产出的是调研报告。通过调研去了解相关竞品的架构模式,甚至是程序实现。当前技术资讯发达、开源社区活跃,太阳底下没有新事物。我们要做的事情,可能已经被人用好几种方式实现了好几个版本。在有限的时间内,找到问题域中最好的几个实现进行调研,站在巨人的肩膀上思考,事半功倍。示例:《蚂蚁 Could IDE 调研报告》[注4]
做架构制图,产出的是架构图。架构制图方法与工具有很多,UML 应该是大部分人最熟悉的制图方法,UML 由以下两大类图组成:
结构图( ):通过对象、属性、操作和关系等方式,强调系统的静态结构,其中最常见的类型包括类图(Class )、组件图( )和部署图( )。
行为图( ):通过展示对象之间的协作关系以及对象内部的状态改变,强调系统的动态行为,其中最常见的类型包括用例图(Use Case )、活动图( )、时序图( )和状态机图(State )。
例如,可以把这两类图应用到我们的程序设计当中:
结构图:程序中包含哪些类、对象和函数,它们之间的关系如何?=>类图(Class )
行为图:程序的运行流程是怎样的?=> 时序图( )
示例:VS Code 插件 Time 的程序设计(来源:#PR 620)
最后关于架构制图,推荐一些方法论和小工具:
方法论:楚衡(.pq) 老师的《架构制图:工具与方法论》一文,系统性地梳理了架构制图的方法和工具,值得一再阅读。
语雀富文本的文本绘图功能,支持 。 是一种绘图语言,可以让作者以类编写 的方式自然地画图,可进行多人协作和版本跟踪,受到各知识系统的广泛支持:
管理项目
完成了产品和架构的设计后,开始进入项目开发的环节。这个环节主要关注的是:如何组织开发和怎样进行协作。前者无论是个人还是团队项目都是通用的,后者取决于项目的规模。
▐组织项目开发
仓库的划分是软件架构设计在代码组织层面的落地,需要有预见性,避免未来进行大规模的仓库迁移。
仓库的组织形式有两种:多仓库和单仓库。单仓库又多包()和单包的区别。比方说 React ,就是多仓库的组织形式:有主仓库 /react 是多包存储库,还有存放周边仓库的组织 /*。
这里面没有一成之规和好坏之分,主要取决于项目的规模和协作上的便利,或者说有时候纯粹是个人喜好问题。比方说有些技术产品将自己的插件、示例、官网都放到单独的仓库进行管理,有些则倾向于放到一起。
示例: 的仓库划分
为了更好地利用 Git 这样的源码版本管理系统来进行多人协作,我们需要制定分支管理策略。分支管理策略的目的是规范化工作流程,让大家高效地进行合作,使得项目井井有条地发展下去。
分支管理策略包含了以下内容:
常见的 Git 工作流有 、 、 、 等等。 的 这篇文章对以上几种工作流进行了比较。
目前社区上广泛采用的是最早由 提出的 :
项目基于 Git 进行源码版本管理,还需要关注分支和标签的命名、提交日志格式等问题。它们的规范性可以使得项目运作井井有条,项目成员对 Git 信息的理解保持一致。社区有很多 Git 规约,它们之间没有好坏之分,主要关注规约的覆盖度即可。
Git 提交日志格式规约包含的内容有:日志的格式、字数的限制、语言的选择等。
在社区中应用得比较广泛的日志格式是:
[optional scope]: [optional body][optional footer(s)]
其中 type 是用来描述本次提交的改动类型,一般可选值及对应含义如下:
Git 提交日志格式规约的完整版本,可参考 Git 。
在项目工程上可以使用命令行工具 ,结合 Git 提交日志格式规约包 --ali,以及 Git Hooks 来进行提交卡口:
安装命令行工具:
$ npm i --save-dev @iceworks/spec @commitlint/cli husky
创建提交日志格式规约文件 ..js:
const { getCommitlintConfig } = require('@iceworks/spec');// getCommitlintConfig(rule: 'common'|'rax'|'react'|'vue', customConfig?);
module.exports = getCommitlintConfig('react');
添加 Git Hooks 配置到 .json:
{"husky": {"hooks": {"commit-msg": "commitlint -E HUSKY_GIT_PARAMS" }}
}
1.@/spec 是淘系前端规约包,内部引用了 --ali
2. Husky 是一个简易配置 Git Hooks的工具
项目工程方案主要包括了代码规约、本地工程和 CI&CD 的内容。
代码规约
在多人协作项目中保持代码风格的一致性是必要的。前端领域关于代码规约的讨论和沉淀都已经比较成熟,阿里前端委员会标准化小组制定了《前端编码规约》 [注5] ,包括了语言(HTML/CSS|Sass|Less/)和框架(React/Rax)的部分。淘系前端基于此规约进行拓展,产出了 @/spec 这个 npm 包,结合 、、 等命令行工具来提供本地工程方面的配套保障。当我们进行项目开发时,只需要引用该包和相应的命令行工具,做一些简单的配置即可:
安装命令行工具:
$ npm i --save-dev @iceworks/spec eslint stylelint prettier husky
配置 .json
{"scripts": {"lint": "npm run eslint && npm run stylelint","eslint": "eslint --cache --ext .js,.jsx,.ts,.tsx ./","stylelint": "stylelint ./**/*.scss","prettier": "prettier **/* --write"},"husky": {"hooks": {"pre-push": "npm run lint"}}
}
本地工程
本地开发工程任务的设定是为了提升开发效率并将团队规约落实到开发中,通常包括以下部分:
setup: 初始化工程环境
dev: 启动调试并预览示例
lint: 执行静态代码分析
test: 执行单元测试
build: 执行源码构建
: 发布代码
前端开发在本地工程配套设施上已经非常成熟,面向不同的项目类型都有相应的工程方案。常见的项目类型和相应的工程示例:
CI&CD
持续集成 (CI) 和持续部署 (CD) 是自动化工作流程的重要组成部分。
在 中,持续集成主要是通过 来实现的。当然还有另外一些选择或结合,例如 、、 等等。 非常强大,可以在任意的 Event 下运行。例如可以在提交代码到仓库时、分支合并时、PR 创建时等等。基于 的任务通常包括:
功能测试及代码覆盖率
代码构建
代码检查(语法检查、安全性检查)
资源部署(CDN 发布、npm 发布)
例如 VS Code 套件 Pack 的 :
PR 创建时:执行代码检查和功能测试任务
提交代码到 beta 分支时:执行代码构建(构建插件安装包)和资源部署(将安装包上传到 CDN)任务
提交代码到 main 分支时:执行代码构建(构建插件安装包)和资源部署(将安装包发布到 VS Code 插件市场)任务
在阿里内部,CI&CD 主要由 DEF[注6] 统一管理,根据不同的项目类型(//)有统一的自动化工作流程。
▐建立协作机制
上图是笔者 2019 年在 上的 ,可以看到有比较多的精力是分配在了与沟通协作的部分(/PR/CR)。对于多人协作开发的项目,前期建立协作机制是提升团队整体工作效率的必然要求。项目开源后,创建贡献指南则可以让外部开发者参与到项目的开发当中。这两者是前后关联的,在有些开源项目中是统一的。
一些社区的贡献指南参考:
Guide for React
Guide for VS Code
在协作机制里面,笔者认为几个重点的内容有:RFC 机制、PR 规约和 CR 指南。
部分技术产品采取 RFC( For ) 的形式进行项目的技术方案设计、讨论与迭代,例如 React RFCs、Yarn RFCs、Rust RFCs 等等。RFC 是一种文档优先的工作方式,并且让方案在项目早期得到充分的讨论和论证。
RFC 机制主要包括了几个方面的内容:
明确范畴:什么时候需要 RFC
设定流程:有哪些环节(提交、审查、实施或延期)及要求,在各环节中各个角色的职责是什么
提供模板:RFC 的大纲
PR 规约的设定目的是为了提升 PR 的质量和提高 CR 的效率。规范化的 PR 还可以基于内容产出产品的更新日志。PR 规约通常包含以下内容:
内容格式的规约:标题和描述应该遵循怎样的格式
提交代码的规约,例如新添加功能需提供测试用例、更新代码需更新包版本号、每次 PR 的文件数和代码行数限制等
合并的规约,例如需要哪些人 才能合并
一些开源项目将 PR 的规约通过 App 来进行保障,例如观察测试代码覆盖率的变化。
高度规范化的 CR 会扼杀生产力,但毫无要求的 CR 又往往是无效的。创建 CR 指南的目的是为了提高 CR 的效率和有效性,在两者之间寻找某种平衡。CR 指南可以包含以下内容:
代码审查标准是什么?
如何确定审稿人?
在代码审查中应该看什么内容?
在代码审查中有哪些文件导航的方法?
代码审查的响应速度应该怎么样限定?