> 团队的存在,就是为了避免个人的不确定性。
这篇文章我持续写了大概有 10 天,每天都写 1-2 小时,边思考边写。内容很多,可能也比较乱,但我感觉没有废话。所以,请感兴趣的朋友,一定多花点时间耐心阅读。
wangEditor(V4.0)—— typescript 开发的 web 富文本编辑器, 轻量、简洁、易用、开源免费。
感谢
首先感谢整个团队成员,对于 wangEditor 的支持和信任。截止本文发布时,团队一共有 11 个人(算上我本人)。大家能无偿加入团队,并且牺牲业余休息时间贡献代码,作为团队的组织者,我感到非常欣慰。谢谢大家!
另外,想加入开源团队的,可以通过 QQ 群,直接联系群主。通过一些考核,即可加入。
参与开源,可提高自己的社区知名度,以及面试的竞争力。在 wangEditor 团队,你可以体验大厂规范的敏捷研发流程,多人协作开发,自主技术方案设计,严格的代码走查。
背景
wangEditor 是我多年以前发起的一个开源项目,我翻了翻我自己当时的博客,2014 年年底就有相关的博客发布。
接下来,就全凭我自己维护,凭着我当时的一股干劲儿,重构升级了 V2 V3 两个版本。代码自己写,文档自己写,QQ 群和 github issues 自己来管理。这期间让我学到很多东西,但也确实越来越分身乏术。
特别是到了 2017 - 2018 年,自己实在是没有业余时间,所以就停止维护了。所以,在 V4 没有发布之前,大家看 github 代码的更新时间,都在 2 年之前了。对此我只能表示很无奈,不甘心,但又没办法。
2020 年春天,我从滴滴离职,业余时间就多一些了。我就想着把这个项目再重新做起来,于是就这样做了几个月,才有了现在的 V4 版本发布。
不过,做之前我认真思考了之前被迫停止维护的最大问题 —— 太依赖于我个人的精力。对于此事,可能很多人都会叹息一声“哎,开源不易呀!”然后不了了之。但是我还是想试一把 —— 个人不行,我就组建团队呀!
不仅仅要作出开源产品
从我决定要“招兵买马”开始,我就为此事定了两个目标。
- 把 wangEditor V4 版本做出来,并且继续维护下去。这个不难理解,做开源都是这样的。
- 探索野生开源项目(非大厂项目,非明星项目)如何通过团队来开发和维护,而且这是一个重点!
也许是我孤陋寡闻,我目前还没有看到有哪个野生开源项目,是通过团队来研发和维护的。即便是有,如他们 QQ 群里有多个管理员,能协助回答问题。但是也没有见谁能把这方面的经验输出,供我参考学习一下。
既然没有(或者有,我没找到),那我就自己干吧。我自己也考过 PMP ,研发项目管理也懂一点。我自己探索出来,哪怕是再少的经验或者教训,输出到社区,这也算是为开源做了一点小小的贡献。
我希望,以后越来越多的项目也能通过团队来维护,而不是单打独斗。一个人做开源,太难了!
我为何要做开源
开源发展这么多年,这是一个老生常谈的问题了,答案无非就两点:
- 情怀层面,工匠精神,为世界输出自己的价值
- 实用层面,增加自己的竞争力,在面试时多点筹码
以上两个理由对谁都是通用的,我当然也是其中之一。
但我要说的,是从我个人情况,我自己的一些的想法,可能并不通用,但大家看看也无妨。
第一,要保持一线编码的能力
从滴滴离职之后,我就没再上班。我想趁还算年轻多体验一下自由一点的生活方式,人生的乐趣在于不同的体验。当然,我是一个闲不住的人,不可能天天玩。我连抖音都没有,也不会玩游戏。
我之前一直兼职做网络课程,现在也在做着。但总是做课程,不在一线编码,慢慢的编码能力会下降的。所以,我必须有一个手段,来持续保持自己的编码能力。开源就是最好的方式。
在这个节奏如此之快的环境,危机意识时刻不能放松。
顺便想说两句废话,发表一下感慨
- 在线教育发展多年,现在的网络课程,绝不再仅仅是“拿 Vue 做一个电商项目”这种简单的事情了,已经到了真实项目、线上业务、解决方案的级别。我就正在参与一门课程,其中项目的复杂度是非常高的。
- 基于我个人的危机意识,大家可以对比想一下,那些专职讲课,而没有其他产出的讲师,他们会不会如我所说,编码能力慢慢下降呢?—— 我不知道,我只说自己。
第二,力争做精一个细分领域
想起了之前看过的两句话,忘了从哪里看的。
- 第一句:不要追求什么前沿的技术,复杂的框架,而要想想,你能通过现有的技术去做些什么?哪怕只是影响一少部分人。
- 第二句:如果你能做出一款能被别人正式使用的产品,你已经超越了世界上 90% 的程序员
我觉得,这两句话当时影响了我的价值观,让我从纯技术思维往业务和产品思维去慢慢转变。
如果要问:软件/互联网行业,技术最厉害的人,是哪帮人?—— 肯定会有很多人回答:xx 框架的作者,xx 博客的作者,知乎 xx 回答问题的人,能解读框架源码的人…… 可试问一下身边的人,我相信这样回答的人,会有很多。
但是我想说,本行业技术最厉害的人,永远都不是那些只关注技术的人,而是能把技术用于产品和业务的人,能通过技术解决业务问题的人。技术本身并不产生商业价值,技术开发出来的产品,产品提供服务,这才产生商业价值,才能给我们发工资发奖金。
所以,我劝大家学习知识,到一定的粒度,能满足正常的开发需求就可以。不要去过多的关注各种奇葩算法,前沿技术,框架细节,什么“Vue 组件通讯的 10 种方式” —— 要那么多有必要吗?(PS:如果为了应对面试,可忽略该段,但应对面试仅仅是临时的)
而且,这是一个快速进步的年代,技术也越来越精细化。你现在需要掌握的事情,说不定过 2 年就有现成的解决方案。例如,说不定过 2 年没有人在回去问你 webpack 如何配置。技术在高速进步,也在高速淘汰,不要冲到这条高速公路上去当炮灰。
在我看来,在任何一个行业,我们都不可能通过纯技术手段保持长久的竞争力。随着自己年龄的增大,工作经验的增多,技术就会变的越来越不值钱。反而,通过技术手段去解决业务问题,解决方案能力,资源整合能力,会变的越来愈重要。而这种能力,不是看看代码,看看书,看看视频就能掌握的,需要大量的时间积累,甚至需要主动尝试主动犯错。
富文本编辑器对应的是在线 office 业务,该业务目前发展飞速。现在你买了新电脑,都不用装 windows office ,直接用现成的腾讯文档/石墨文档就行,非常方便。
我如果去研究在线 office 整个系统,这个不太现实,我没有那个环境,我也没有啥优势,而且这个范围太大,我也精力有限搞不了。而富文本编辑器,及其周边解决方案(如协同编辑),搞这个正合适。
一个行业的发展和成熟,必定会带来领域的精细化分工。即专业人做专业事,大家协作,而不是一个公司啥都做。这是自然规律。所以,抓住一个精细领域,研究好了,未来相信会有机会。
组建团队的另一个目的
团队的存在,就是为了应对个人的不确定性,这样就能让业务更稳定运行。所以,各个公司都是以团队的形式存在的。
同理,我组件团队来维护开源项目,也是为了能稳定的研发和维护项目,而不仅仅依赖于我个人的精力。
但是,除此之外,我还有另外一个目的,关于我个人的成长和转型。
我此前都是一名程序员,靠技术吃饭。虽然现在这碗饭吃的还挺香,但也要居安思危(但也别搞的太焦虑,甚至抑郁了~)。就像网上热议的“35 岁之后事业”这个话题。
我一直觉得,无论是哪个行业的技术人员,从大学毕业到 30 左右,都是积累个人技术能力和经验的阶段,靠技术吃饭没问题。
而过了 30 岁,就要考虑转型:个人能力 --> 资源整合能力。
资源整合能力有很多种形式,不同的人也有不同的看法。总之就是,不要再个人单打独斗,而是要聚合一部分人,做一个团队,无论是公司全职的还是业余兼职的。自己的工作就是让这个团队运作起来,而且要运作的稳定,持续,高效,有节奏。此事没有既定的标准,必须通过实践才能慢慢磨练出来。
我组建这个团队,也是想对于自己资源整理能力做一次实践。这对我来说也有很多的挑战。
- 产品业务上,我要参与讨论,评审各个需求,保证简单易用
- 技术上
- 第一,设计整体框架,搭建开发测试环境,CI/CD 流程,尽量让大家关注于业务开发
- 第二,制定编码规范,研发规范,开发文档等,人多了无规矩就乱套了
- 第三,评审技术方案设计,保证设计的合理性,可扩展性,还要严格审核每个 pull request ,做 code review 。认真做好每一次,否则很容易发生“破窗效应”
- 项目管理上,现在有很多任务并行开展,要有条不紊,不冲突,尽量不延期
- 团队建设上,我要招聘考核新成员,做新成员,制定团队纪律和规范,定期和成员 1-1 沟通,保证合作没有隔阂
- 未来规划上,要考虑未来 1 年要做的事情
上述这些事情是我目前能想到的,毕竟我也就搞了几个月。相信以后会有新的内容补充,到时我再继续产出文章吧。
这么多的事情,相信会给自己带来更全面的成长。虽然做开源是不挣钱的,但它并不是无用功,它会产生价值。我相信,只要是价值,就一定会有机会变现,在未来的某一天。
团队建设
下面来点干货,写写建团队,做项目的一些过程。
为何要无偿加入团队?
文章开头先感谢了团队的所有成员,他们无偿加入团队,每天晚上和周末贡献代码。那大家为何会加入团队,这是我必须思考的一个问题。即,这个团队的吸引力在什么地方,以及还有哪些地方做的不好。
我跟各位成员 1-1 沟通的时候专门问过这个问题:自己加入团队的预期是什么?想通过团队提升自己的什么能力呢?
各位成员的答案也都比较一致。大概就是公司里项目比较简单,都是做业务,想通过一个开源项目提升一下自己的能力。还有几位成员没有毕业,或者正在实习,也想通过这个来增加自己的项目经验。还有一位是大厂的员工,因为刚加入不久,我还没来得及 1-1 聊。
大家应该都没有很详细的思考过这个问题,到底具体有那几点,能提高的自己的编码能力。不过这个没关系,至少从现在来看,团队氛围是比较和谐的,大家产出也都比较积极,合作很愉快。安排的任务也能积极得到响应,尚未发现沟通困难的成员。
我记得之前有一位成员表示,加入团队 2 个月,比自己在公司干 1 年的成长都要快。谁说的我忘了,如果你看到了可以在下面评论回复一下。
我来替各位成员总结一下,加入开源团队之后,有哪些地方可能会促进成员的成长。(PS:有一个背景需要提前说一下,我们团队现有的成员以小厂员工,实习生还有未毕业的学生,为主体,不过也是经过面试考核才进来的。关于这些,我后面有写,慢慢看)
- 敏捷研发流程。研发项目管理在软件中很重要。
- 技术方案设计。之前是有需求就直接写代码。而现在是有需求先写技术方案设计文档,评审通过之后,再写代码。
- 严格的代码走查。目前我对于每一次 pull request 都做严格的代码走查,防止破窗效应。
- 多人协作开发。之前自己在公司可能就一个人做,不知道如何多人协作开发。
- 文档意识。我们有自己的知识库,所有的文档,表格都记录在案,有知识积累。
- 做开源项目的成就感。有成员表示,他参与的这个项目,公司的其他同事都知道,他就很有成就感。
随着 v4.0 的发布,大家参与的事情会越来越多,越来越全面。后面大家还会参与运营和运维工作,例如 QQ 群答疑,github issues 回复和记录,产品迭代升级,新技术方案调研。
即,v4.0 发布之前,大家参与的是一个一个单功能的开发工作,而 v4.0 发布之后,大家参与的就是一个完整产品的运维工作。从单功能开发 -> 产品运维,上升到了一个更高的维度。
招聘新成员
从开始招聘,到现在,一共通过了 13 个人。其中有 1 一个人,加入之后又退出了,还有 2 个人,通过考核之后没继续加入进来。具体原因我也不深究了。所以,现在一共 10 个人,再加上我,一共 11 个人。当然,你在阅读本文时,说不定人数又变了。
招聘渠道
- 在 wangEditor 两个 QQ 群发公告。
- 在 wangEditor 官网和文档发公告。
- 他人介绍
有意向的成员,加入 QQ 群,然后私聊群主(就是我),进行面试考核。毕竟我们招聘的人也不多,所以就人工聊天即可,能应付的过来。
面试考核
QQ 联系到我之后,我二话不说,先发一个任务过去。任务大体就是:用 webpack 和 ts ,从 0 开发一个简单的富文本编辑器,代码放在 github 上,然后写一篇博客记录开发的过程。一周之内完成。
这里就很有意思了。上文说我招聘通过了 13 个人,但是给我发 QQ 消息的,我估计,得有 50 个人左右。即,大部分人都在这一轮自己放弃了。真的是自己放弃的,我没有主动拒绝过一个人。即便是他任务完成的不好,我也会引导着让他继续做完,而不会拒绝他。
我很庆幸我以这样的形式来考核成员,而不是以电话或视频面试的方式。面试是一问一答,没法考察主动性和动手能力。我们是一个业余的兼职团队,相比于技术能力,我们更需要的是积极,自驱和动手能力。所以,如果你连我安排的任务都不想做,或者做不了,又不想主动去学习去查询,那你进入团队也无法胜任开发工作。
接续,只要通过了考核,我就会再去安排查阅我们的一部分开发文档 https://github.com/wangeditor-team/wangEditor/blob/master/docs/README.md ,在 github 中,是公开的。并强调,要仔细看,认真看,不求快,看完了主动联系我。这里完全靠自觉,因为文档看不好,那以后开发也会遇到阻碍。
这里很强调主动性。做完任务要主动联系我,看完文档还要主动联系我。如果你不主动,那我就视为你放弃了。
因为,此时你不主动,那将来进入团队开发任务,也不会主动。
待看完文档,基本就确定完成考核了。再聊聊天,了解一些基本信息。
加入团队
这一步很简单
- 拉到微信群(后面考虑转钉钉),和其他群员打招呼认识
- 拉到 https://github.com/wangeditor-team
- 拉到 teambition ,这里是所有的任务管理
- 拉到语雀,这里是项目知识库,放着所有的文档
新成员自我培训
加入团队和加入公司一样,第一步就是新员工培训。只不过大公司会在培训时讲解企业文化和价值观,而我们团队目前还没到那个层级,仅仅是学习和了解一些规范,制度,纪律等。
而且,我们这是自我培训,即自己看,没人给你讲。有问题你主动去问。还是要主动)
我在语雀有《新员工自我培训手册》,里面列着所有的代码规范,流程规范,沟通规范,团队纪律等。总之,就是在团队合作开发需要了解的一些基本信息。
既然是自我培训,如何判断有没有看完呢?最简单的方式,就是常见的打卡机制。新成员看完培训手册之后,写一篇打卡记录,发到群里。
培训手册最后一句话“待以上步骤都完成之后,主动联系导师,开始认领开发任务”。还是要主动,一切事情都是自驱的。
团队纪律
- 兼职远程合作,最大的问题就是:沟通
- 多人协作,最大的问题就是:规范
所以,团队纪律就围绕着这两点 —— 沟通和规范。
沟通纪律
- 所有的沟通,都要保证傻瓜式,即说大白话,让别人都能看懂,哪怕多重复几句。这一点很重要,有时候你简单说几句,以为别人懂了,其实人家没懂,还要反问,你再继续解释,浪费时间。
- 所有的关于自己的沟通,都要有回复,即有来有往。否则别人也不知道你是不是真的收到了。
- 微信群里发的,以
【通知全员】
开头的信息,所有成员都必须回复。不要求秒回,至少 12h 内要回复。说实话,这一点我们现在执行的不好,每次发【通知全员】,大概能有一半的人回复。这一点我再继续想办法完善流程。
规范纪律
无规矩不成方圆,一切按照语雀里写的开发规范和流程规范来,不可自造规范,不可跳过任何的必要流程!
如果觉得规范不合理,可以提出来,讨论再次修改规范。如果有特殊情况需要跳过某个流程,也需要提前报备。
我在组建团队之前,就花了大量的时间来写规范。具体这些规范有哪些内容,有机会再分享吧,本文内容已经很多了,不再去写这些细节了。
汇报和沟通
业余,兼职,远程办公,最大的障碍就是沟通。无论我们怎么努力的做,也做不到办公室集中办公的沟通效率和效果,这个很无奈。不过该做的还是要做,做不到 100 分,能做到 70 分也不错呀。
日常沟通
日常沟通就在微信群里,@ 别人讨论问题,或者 @ 我反馈进度,例如文档写完了,pull request 提交了等等。我审核完之后也会在群里 @ 成员回复结果。
如果某个成员有单独的问题,也会私聊我讨论。我们聊天,或者干脆打电话说。
但需注意,这里所有的聊天,讨论,电话等,都是一个过程,它所产出的结论,我们都会记录文档,并且统一记录在 teambition 的任务卡片里。即,我们不在聊天中传递结果信息,结果信息都要有统一的记录,这样方便查找和回复。
PS:这里也体现出了一个文档记录的意识,即团队要有自己的知识库,这非常重要。
周会(后来取消了)
刚开始组建团队时,算上我只有 3-4 个人,那段时间周末会开一个剪短的周会,远程电话会议。但开了几次之后,感觉周会真的没必要每周都开,因为没有那么多事儿可聊。
如果是公司办公,领导开周会,可能还会贯彻一些公司的文化,规范制度,甚至还有一些鸡汤大饼什么的。而我们这个开源团队,也不是公司,没必要整那些东西。所以,当时讨论了一下,就决定暂停周会。
后来人多了,再开这种电话周会,就更不可行了。所以,至此一直没再开过。
不过,我这几天想来,这种集体性的会议和沟通,还是要定期开一次的,例如每个月开一次。现在投屏开会也很方便,用腾讯会议就能轻松做到。每月开会,总结之前工作,制定接下来的计划,给大家同步一下信息。这个我后面会安排起来的。
周报
当前主要的沟通汇报机制,就是每周日晚上写周报。
大家上班,可能每周也都要写周报。不知道大家有没有考虑一下,写周报到底是干嘛的呢?我猜想有人可能说:周报吗,就是领导为了监督大家工作的,看看谁偷懒了 —— 在上班工作的环境下,有可能是这样的。但在我们这个开源团队中,周报并不是为了监工的,因为我们业余无偿的工作,允许大家无条件延期,和有计划的偷懒。
我觉得,我们团队中,周报的作用,是为了让各位成员自己总结本周工作内容,做下周计划。每周对自己的工作做一个总结,和计划,这就让工作具备了节奏性和阶段性。这就能让自己意识到,哪些工作得抓紧做了,哪些工作可以不着急,从而就对自己有了规划性。相反,如果我们没有周报,没有总结和计划,每天都浑浑噩噩的来,当一天和尚撞一天钟,那效果会差很多。
所以,即便是大家上班工作,周报的做用也绝对不仅仅是领导监工。奉劝大家认真对待周报,不要敷衍,周报本来就是你个人提效的一个好工具。
经过几次调整,我们周报目前的格式如下。
- 日期范围,即本周
- 本周工作内容
- 本周工作时长(单位 h)
- 相关链接
- 下周工作计划
周报格式也是经历了一些调整的,根据调整的经历,我觉得有两件事儿非常重要。
第一,本周工作时长。即,每个成员都要回顾一下,你本周一共花了多少 h 在这份工作上。而且,时间要和工作内容想匹配,所以不能瞎写。我们之前有规定,如果持续每周产出都在 2h 以下的话,将会被暂停工作。当然,如果实在忙起来,可以提前请假报备,凡事都要有计划性。
第二,相关链接。本周工作内容是文字描述,口说无凭,链接为证。文档的链接也行,代码的链接也行,总之得有工作产出,得有交付物。这也就敦促大家,所有的工作都要有过程记录,该写文档的别偷懒,否则你这工作内容就不真实了。
还有一件值得记录的事情,就是大家经常会忘了写周报。然后第二天表示抱歉,再补上。忘了某件事,人之常情,这容易理解。不过也有一些技巧,推荐大家使用 todo-list 工具,带有时间提醒的。我也经常会忘事,不过有了这样的工具,就很很多。
1-1 沟通
1-1 沟通在企业团队管理也是常用的手段,就是一对一的和团队成员聊聊天。既然是 1-1 私聊,也就没有开会聊的那么正式,可以聊一些工作之外的事情。
我会大概 1-2 个月时间找各位成员,打电话聊一次,时间不固定。聊的内容,常规的有:工作的感觉是否正向,对团队有哪些建议,有哪些吐槽,有哪些让自己感觉不舒服或者困惑的地方。即,有问题大家直接提出来,别憋在心里,时间久了会造成很多负面的情绪,影响工作效率和积极性。
关于团队的兼容性
这个话题,我的观点可能和大家的不太一致。
大家经常会遇到这样的情况,例如发生了某个 bug ,最后背锅的往往是处理这个问题的程序员,或者某个基层员工。然后就怪罪这个员工水平不行,连最基本的 xxx 都不知道,导致了这个 bug 。(当然了,这也许是办公室政治的一种表现形式,有人的地方就有江湖嘛)
对此,我有自己不同的看法。我记得很多年之前我考 PMP 时,学到了一个至今难忘的观点:领导层 75% 责任。即,无论发生了什么问题,领导都要占据 75% 的责任,而实际开发的成员也只占据 25% 的责任。
如果这个团队成员是恶意的犯错,就想删库跑路,那是另外一回事。如果他是无意引发了这个问题,那就得怪罪负责人和团队流程,没有把事情考虑周全。例如,他开发完了,没经过测试就上线,导致了 bug ,那这就得怪流程不完善,不测试怎么能上线呢?
回归主题,我认为,一个优秀的团队是有兼容性的。它能兼容所有水平的员工,只要基本能力过关,态度积极,都可以通过团队的流程和规范,来做到符合预期的工作。负责人的价值,是要让团队有序高效的运转,手段就是要制定团队的流程和规范,而且要有手段来保证成员按照规范执行。如果成员按照规范和流程去执行,他就一定能达到目标。PS:当然,优秀的员工,能做超出预期的工作,这当然是好事情。
同理,一个优秀的项目架构,也能兼容任何代码,做到充分的解耦,即便有的地方代码写的烂一点,也不会影响全局。哪天想重构这个模块,能一次性把烂代码替换掉。
这不前几天,我们团队的一位成员,无意删除了代码的 dev 分支,我一开始也怪罪了他几句,这是一时的意气使然。当问题解决了,我平静下来之后,自己复盘这个问题,其实这也是我的责任,或者我们团队研发流程的责任。dev 这么重要分支,为何不加一个保护呢,github 本身就支持分支保护。所以,我现在就加了 dev 的分支保护(master 分支保护早就有)。
这种兼容错误的团队流程,也是通过犯错来一步一步完善起来的。但是前提是你要有意识的去考虑负责人和团队的责任,而不是让某个成员背锅。否则,团队流程的兼容性是做不起来的。
这里不是说我们的团队和技术架构有多优秀,但我会按照自己的想法,继续慢慢的做好。
研发管理
从一开始重构 4.0 到现在,基本都是研发任务。分配一个新功能,然后开始写需求,设计,写代码,走查,最后合并代码并发布。
任务流程
我们使用 teambition 做任务管理,类似于敏捷项目研发流程。
但遗憾的是,随着现在成员增多,teambition 要收费了,而且收费还挺贵。我正在调研其他的任务管理系统,目前还没有找到合适的。
国内的这些系统,都要收费。github 自带的有任务管理,但是功能比较弱,目前还在观望中。
不过,后面我也在考虑划分产品方向,待 V4 发布之后,我就开始试运行。一个方向如果超过了 10 个人,确实也不是很科学的组织方式。
阶段1 - 分配任务
创建新的研发任务,分配责任人,分配开始和结束时间。这些操作都是我来做的。
创建任务时,任务的备注里要写清楚做什么,写的越清楚越好。这就是上文提到的“傻瓜式沟通”的纪律,我自己也时刻在执行。
任务的结束时间,是我评估的。但是我们允许无条件的延期,即结束时间到了,自己再修改一下结束时间即可。毕竟我们是业余的兼职团队,确实也没办法保证工作时间,这个大家都能理解。
但是我最近发现了一个问题。大家觉得可以无条件延期,然后每次修改结束时间时,都不会认真考虑,就随便改一个完成时间。等过两天又延期了,就再改一个。我觉得这是一个很没有计划性的事情,我再去想办法解决,不能任其发展下去
阶段2 - 需求和设计 - 先说需求
需求指导设计,设计指导开发。这是一个串型流程,前面做不好,后面就会有风险。
如果是新功能开发,涉及到 U I,或者用户 API ,是必须写需求文档的,就写在语雀里。写完之后,交给我做需求评审,我会回复评审建议。一般情况下,都要经过 2-3 轮评审,需求才能通过。至此,我们已经积累了很多需求文档。
大家可能会疑问,程序员需要写需求吗?不都是 PM 提需求,然后程序员开发就行了吗?对于这个问题,我的答案很坚决:程序员一定要积极参与到需求中去,并且要尽快了解需求和业务。
在大公司,人才多,方向划分明确,有专业的 PM 写需求,交给程序员开发,但程序员也要积极参与到需求评审会议中去讨论,如果自己对于需求有疑问,也要提出来。
在小公司小团队,人比较少,那就只能让大家多多承担需求的工作,就是直接去写需求。但是,这种方式也是参与需求的最好方式。
本文上面提到过,程序员随着年龄的增长,技术的竞争力会逐步下降,所以要结合业务和技术,也就是要深入到需求中去。《聊聊架构》书中提到,现代互联网企业的人员组织形式,越来越趋向于全能型人才,小团队作战,提高效率。
团队成员在写需求的时候,都有一个很常见的问题,就是过度的参考别的产品,把所有功能都搬过来。所以在我做需求评审的时候,都会砍掉一些需求。
那些比较成熟的产品,他们的功能都是很多人花了大量时间,而且是专职工作时间,慢慢做起来的。但像我们这种刚开始做的产品,不应该追求那么全面的功能。根据 2/8 原则,我们能先把 20% 的常用功能做好,能满足用户 80% 的场景,就已经可以了。其他的,后面再根据用户反馈迭代升级。
另外,写需求时也要考虑后续的设计和实现。需求越复杂,设计就得越复杂,代码就复杂度增加。第一,这会增加开发时长;第二,这会增加后续 bug 出现的概率。
阶段2 - 需求和设计 - 再说设计
这里的设计,就技术方案设计,并不是 UI 设计。
按照我们的研发规范,所有的开发任务(除了简单的 bug 修复)都必须写技术方案设计。需求知道设计,设计指导开发,无设计不开发。而且,写完了还要交给我来评审,一般需要评审 2-3 轮才能通过。至今我们积累了这么多技术方案文档。
所谓技术方案设计,直白来说,就是写一写你打算怎么开发。因为我们是多人协作开发,你不写出来,直接去开发,写出代码来我也看不懂。所以,设计是多人开发中一个非常必要的沟通过程。
技术方案设计没有规范的格式,我们也不限定格式,可以参考着已有的文档来写。例如,你要新建或者修改哪些文件?你要创建几个 class ?核心功能的实现逻辑是什么?实现之后生成的数据结构是什么?有没有技术难点?打算怎么做单元测试?—— 等等吧,就是这个功能开发的一些关键点,不要细节,但要全面,要能说通说明白。
有些朋友可能觉得技术方案就是一个形式,觉得自己直接开发代码就行了,写技术方案是浪费时间 —— 此时大错特错!!!我们从两个方面的分析:
- 如果你真的了然于胸,直接写代码就可以很轻松的实现,那这样的话,让你去写个技术方案文档花不了多少时间吧?你都那么熟悉了,那最多 1h 也就写完了。你会因为这 1h 而延期吗?我从没见过这样的延期原因。
- 但是,如果你觉得自己很熟悉,但是写文档就是迟迟写不出来,那你还是自我反思一下,你真的那么熟悉吗?还是自以为很熟悉?你文档都写不出来,那我不相信你能很快吧代码写出来。所以,写文档的过程,也是一个检验的过程,及早发现问题及早解决,或者及早调整开发计划,等开发时再发现再修改,就晚了,就延期了。—— 延期往往是这样发生的,而不是因为花 1h 写文档而导致的。
之前有新加入团队的成员反馈,自己没写过技术方案,也不知道咋写。看着文档写不出字来,就像直接去开工写代码。
这就是一个技巧的问题了。这个阶段是写设计文档,但不是说不让你写代码。你可以先开始写代码,找一些灵感,做一些验证和测试,然后再把设计文档写出来。虽然你写代码了,但这个阶段不叫开发,你的产出也不是代码,还是设计文档。
据我观察,技术方案设计在各个公司执行的都不好,无论大厂还是小厂。它就像单元测试一样,大家都觉得是个好东西,但就是很少人真正执行起来。我想应该是大家对它的理解和应用有偏差,没有找到它的真正价值。但对于我们团队来说,技术方案设计,会持续执行,而且会继续优化。
阶段3 - 开发和自测
需求确定了,技术方案设计通过了,再去开发就简单多了。
自测,目前执行的不太好,但这个过程还是很重要的,所以我会继续做起来。
没做好,我觉得原因是:第一,没有把自测固化到流程中;第二,太依赖于个人的主动性,应该交叉测试。
阶段4 - 提交 PR,即 Pull Request
根据开发规范,新功能(或 bug)开发时,需要新建 git 分支。开发完之后,提交 git 分支,然后提交一个合并到 dev 的 Pull Request 。我们不允许直接操作 dev master 等公共分支。
注意,提交 Pull Request 之后,要求提交者先自己看一看 Files Changed ,万一有一些低级错误,能自己发现自己修改。
曾经出现过这样的问题,我收到 Pull Request 之后一眼就看出了低级错误,然后驳回重修改,浪费时间。大家都要对自己的产出结果负责,认真一点,不要无脑提交。
然后基于 Pull Request 做代码走查。代码走查我会做的非常详细,主要看
- 代码逻辑是否合理
- 代码注释是否规范且合理
- 单元测试,用例是否完整
- 开发文档,使用文档,是否齐全
- 全局事件,是否会造成其他干扰?
- 定时器、自定义事件,是否有内存泄漏风险?
代码走查如果有问题,会在 Pull Request 上回复评论意见,并通知开发者。
开发者根据评论意见,继续修改,然后重新提交,重新代码走查。一般情况下,都要经过 1-2 轮,才能审查通过。
阶段5 - 待发布
Pull Request 代码走查通过之后,就会被合并到 dev 分支。至此,开发任务也就全面结束了,开发者可以放下去做其他任务了。
但此时尚未发布到 npm 。
阶段6 - 已发布
每隔一段时间,就会把当前积累的待发布功能,从 dev 合并到 master ,发布到 npm 。这些功能就已发布了,彻底完成了。
当然了,如果是紧急 bug 的修复,那就尽快发布到 npm 。常规功能,就按计划每周发布一次。
后续的 bug 修复流程
bug 修复,改动范围小,和研发任务不一样,不在适合用这种任务管理。更适合用 bug list 来管理,而纯表格又不太适合做任务跟踪。
此时倒是可以考虑使用 github 的任务管理,因为它可以和 github 的 issue 和 pr 联动起来,效果应该不错。我会去尝试用一下。
知识库
一个正规研发团队,必须要有自己的知识库。我们选择语雀来作为知识库,把所有的文档,流程,记录都记录在里面。新成员加入的时候,可以通过这些文档快速了解业务和代码。
不过,经过这几个月的使用,目前感觉这些文档已经有点混乱了,我后面会继续整理一下,重新分组。
在招募新成员时,我一直强调,我们虽然是业余的开源团队,但是正规军的作战模式,并不是散兵游游。我们有正规的研发流程,研发规范和知识库,这些都是一个研发团队的标配。
所以,如果你还在一个不太成熟的研发团队上班的话,加入我们会让你快速熟悉正规研发团队的管理方式。这也是我们吸引新成员的价值之一。
代码架构和技术基建
上文提到过,优秀的团队有兼容性,它不挑成员。同理,优秀的软件架构设计,也是有兼容性的,它不挑代码。即便是某一部分代码写的不太好,也不会影响全局,要做到充分的解藕。
另外,技术基建要做好,如 CI/CD 。这样才能让开发者专心关注于业务代码,而不是在各个环境里疲于奔命。
最后,就是要通过一些技术手段,来尽量保证代码的可读性和稳定性。例如 eslint 单元测试等。
技术选型
现在大家都用 ts ,再不用好像显得有点 out 了。再者,ts 提供的强类型,也确实有利于多人开发的代码规范。而且,对成员有了更高的要求,能有利于筛选更优秀的成员。
富文本技术我们一直使用老旧的 document.execCommand
API ,这也是没有办法的事情。我们这是正儿八经的做开源产品,又不是专业做技术调研,所以还是要尽快的输出产品,不能一直钻研技术。但新的技术方案,即自己实现 execCommand,会马上启动调研,下文会有介绍。
代码结构
代码结构我专门写了开发文档 https://github.com/wangeditor-team/wangEditor/blob/master/docs/code.md ,而且还为此录制了大约 1h 的视频来介绍。代码要充分解藕,并且模块清晰。
菜单之间相互分离
所有的菜单都在 src/menus/
下,不同的菜单都是一个独立的文件夹,互不干扰。
而且,针对不同类型(Button,DropList,Panel)的菜单,都可以根据不同的 class 进行继承。
最后,菜单除了自己开发以外,还支持让用户自己去扩展,已有文档说明。
可扩展 text 监听事件
text 即编辑区域。编辑区域的各个事件,都是实现功能的必备手段。例如,图片被点击时,显示拖拽功能。于是,就有了 textEventHooks 这种事件机制,可扩展。
// 各个事件钩子函数
type TextEventHooks = {
changeEvents: Function[] // 内容修改时
dropEvents: Function[]
clickEvents: Function[]
keyupEvents: Function[]
tabUpEvents: Function[] // tab 键(keyCode === )Up 时
tabDownEvents: Function[] // tab 键(keyCode === 9)Down 时
enterUpEvents: Function[] // enter 键(keyCode === 13)up 时
enterDownEvents: Function[] // enter 键(keyCode === 13)down 时
deleteUpEvents: Function[] // 删除键(keyCode === 8)up 时
deleteDownEvents: Function[] // 删除键(keyCode === 8)down 时
pasteEvents: Function[] // 粘贴事件
linkClickEvents: Function[] // 点击链接事件
codeClickEvents: Function[] // 点击代码事件
textScrollEvents: Function[] // 编辑区域滑动事件
toolbarClickEvents: Function[] // 菜单栏被点击
imgClickEvents: Function[] // 图片被点击事件
imgDragBarMouseDownEvents: Function[] //图片拖拽MouseDown
tableClickEvents: Function[] //表格点击
menuClickEvents: Function[] // 每个菜单被点击时,按理说这个不属于 txt 的,先暂时在这放着吧
dropListMenuHoverEvents: Function[] // droplist 菜单悬浮事件。暂时放这里
splitLineEvents: Function[] // 点击分割线时
}
如何使用这些事件呢?可以拿图片菜单举例子。图片菜单在初始化时,会执行下面这一段代码。
/**
* 绑定事件
* @param editor 编辑器实例
*/
function bindEvent(editor: Editor): void {
bindPasteImg(editor) // 粘贴图片
bindDropImg(editor) // 拖拽上传图片
bindDragImgSize(editor) // 拖拽图片尺寸
bindTooltipImg(editor) //Tooltip
}
其中的每一个绑定,都会用到上述的事件。例如 tooltip
/**
* 绑定 tooltip 事件
* @param editor 编辑器实例
*/
function bindTooltipEvent(editor: Editor) {
_editor = editor
// 点击图片元素是,显示 tooltip
editor.txt.eventHooks.imgClickEvents.push(showImgTooltip)
// 点击其他地方,或者滚动时,隐藏 tooltip
editor.txt.eventHooks.clickEvents.push(hideImgTooltip)
editor.txt.eventHooks.keyupEvents.push(hideImgTooltip)
editor.txt.eventHooks.toolbarClickEvents.push(hideImgTooltip)
editor.txt.eventHooks.menuClickEvents.push(hideImgTooltip)
editor.txt.eventHooks.textScrollEvents.push(hideImgTooltip)
editor.txt.eventHooks.imgDragBarMouseDownEvents.push(hideImgTooltip)
// change 时隐藏
editor.txt.eventHooks.changeEvents.push(hideImgTooltip)
}
关于控制 editor 权限
有成员之前提出过一件,说 editor 不能把自己所有的能力都暴露给菜单,这样很容易造成破坏性,要有权限控制。
我感觉确实挺有道理。不过,目前还没有想到怎么去具体落地,而且还有保证复杂度不高。这一点我们再继续讨论,慢慢改进。
单元测试
单元测试是保证软件功能稳定的最有效手段之一,所以我们在每个技术方案设计时,都要求写明单元测试该怎么做。
不过,富文本编辑器这种富 UI 操作的软件,单元测试确实不太好做,至少不太好做全面。我们现在的单元测试覆盖率也不过 60% 多一点,也只能算刚刚及格。
但是,不好做归不好做,但是可以做,至少我能通过单元测试来保证一部分基本功能是正常的。这也能大大减少我们的工作量,提高一点我们的稳定性。
单元测试我打算以后专门做一次专题调研,看看如何能再继续优化一下。这有可能需要调整一下代码,例如把一些可供测试的逻辑单独抽离出来。
CI/CD
CI/CD 是前端的一个热门话题,这也确实该热一热,因为这的很有用,很方便。我们使用 github actions 做 CI/CD ,易学易用。
自动构建
当 dev 和 master 分支 push 时,会出发自动构建。执行 npm run lint
npm run test
npm run build
,以保证代码构建是没有问题的。
将开发分支发布到测试机
上文提到过,开发新功能或者修改 bug 时,要拉新的分支,分支名是 feature-xxx
或者 fix-xxx
。遇到这两个格式的分支,会触发自动构建,并且将构建结果推送到测试机(我自己买的一台腾讯云服务器)。然后通过 http://106.55.153.217:8881/feature-xxx/examples/index.html
来访问,其中 feature-xxx
可以换成别的分支名。
这个功能还是很重要的。当自己开发的功能,需要发给别人测试或者试用时,直接 push 分支代码,发这个测试机链接就可以。
自动发布到 npm
代码合并到 master 分支,然后 push 一个 tag ,即可触发构建,并且执行 npm publish
发布到 npm 。
开发文档
开发文档在 https://github.com/wangeditor-team/wangEditor/tree/master/docs ,这是公开的,给感兴趣的朋友,或者新加入的成员查阅的。PS:放在 github 的内容肯定是公开的,但在语雀的文档是不公开的。
注意,在看开发文档之前,一定要先去看一下使用文档 。先看使用,再看实现。
开发文档内容不多,包括最关键的亮点
- 代码结构。了解源码,了解运行机制。
- 开发规范。如果你想要贡献代码,无论是正式加入团队贡献,还是以用户身份提交 Pull Request ,都必须按照这个规范来。
团队遇到的问题
业余兼职,远程办公,这样的团队遇到的问题无非就两点:沟通 + 进度保障。
我们无法像办公环境下那样当面沟通,只能通过微信聊天,电话,看文档这种方式来沟通。由于我们当前的研发流程比较规范,一步一步来,每一步都有文档,都有审核,审核也算是沟通。所以,目前沟通的问题并不大,虽然效率没有那么高,但也有节奏的进行中。
进度保障这就有点难了,业余工作,没有强制加班,全凭自觉。所以,这方面干脆就放开,允许大家有计划的延期,不设置 deadline 。当然,如果有的任务持续没有进展,我会单独跟进一下,问问有没有啥问题。
总体来看,上述这俩问题的实际表现,我还是比较满意的,本来嘛也是现实情况,能做到这样就挺不错了。
未来的计划
争取通过 1 年的时间,做到国内体验最好的开源编辑器。不敢说能做到腾讯文档/石墨文档那么专业复杂的级别,但也至少能满足其他场景的使用需求。
随着团队成员的增多,需要划分一下不同的方向。目前计划的方向有:
编辑器维护和升级
第一当然是修复 bug 。有 bug 并不可怕,因为这个世界上只有两种软件:第一是没人用的软件,第二是全是 bug 的软件 —— 只要有人用,就肯定会有 bug 。问题是,如何收集 bug(如 QQ 群,github issues),识别优先级,以及如何高效稳定的去安排 bug 修改,并监控进度。
第二是要继续开发新功能。注意,新功能的开发一定要根据用户的反馈来,而不是自己以为什么重要就开发什么。
第三是要持续保证代码的规范和质量,保证流程的高效和稳定,保证知识库的有序整洁。例如,随着新功能的增加,模块越来越多,是否要考虑拆包,按需异步记载?
以上这些,都是从 1 到 2 的过程,比从 0 到 1 更加复杂,更加具有挑战性。不过我很期待。
“孤岛”
这个词我不知道用的合不合适,也是我自己取的。专业术语叫什么(或者有没有专业术语)我还不知道。
我们常说的富文本编辑器,其实就是文字图片等等的编辑。但现在的编辑器,已经不仅仅是图文了。你可以随意插入表格,代码块,思维导图,附件,而且还能结合富文本操作进行编辑。
所以,编辑区域除了图文之外,我们还需要一个一个的“孤岛”,其中存放表格,代码块,思维导图等。每个孤岛里,都有其本身复杂的操作,但对外面的图文不会有任何影响,就像一个 iframe 一样。这样才能充分解藕,符合软件设计原则。
这个方向未来会安排专人去调研。看起来比较难,但是没关系,我们慢慢做。
自研 document.execCommand
上文提到过,我们现在还是用的老旧的 document.execCommand
API ,但自研是势在必行的,会高优安排。
自研的 document.execCommand
从使用者来看,最好要和原生的 API 保持一致,这样应用时就不用改动太多代码。
做在线 office
做这个不是为了和专业在线 office 系统竞争,我们暂时也没资格和人家竞争。
做这个,第一是自己亲自用一下编辑器,体验一下哪里好,哪里不好。还有,更重要的是,我们要探索富文本编辑器周边相关的解决方案,例如多人协同编辑。即,我想我们未来产出的不仅仅是一个富文本编辑器的工具,而是一套和富文本相关的一系列功能和解决方案。
解决方案是可以商用的。
总结
大家可能觉得我是在招募免费劳动力,为自己干活 —— 这完全错误了!
- 我们做的本来就是开源项目,不是盈利性质的,大家的工作都是无偿的,我也是。如果非要说招募免费劳动力,那我也是先把自己搭进去了。
- 加入团队的成员,都会得到自己的成长和收益。而我作为团队的负责人,通过管理团队也得到了自己的成长。我们是共同进步,各有收益。
- 大家加入或者退出都是自由的,是不是对自己有价值,大家会用脚投票,我们没有任何强制也没法强制。
最后,再次感谢团队的所有成员!
对了,继续招募新成员,也欢迎 PM UI QA 角色。
热门评论
最近在在为明年换工作(想进大厂)复习,听了老师的前端面试课(还没看完),感觉老师是一位思维严谨的人,能学到不少东西。之前对开源就挺感兴趣但是一直不知道如何参与。希望明年能顺利跳进大厂,然后再看看有没有机会参与老师的这个开源项目。
学习完老师的课程,就报名!!!