最近半年加入了一个新团队,并从头开始规划一个团队和 WebApp 项目。一切都是新的,新的团队成员,新的领导,新的环境。
我想,可以避免一些弯路,可以做出一些尝试。
项目立项
一个仪式,主要作用是:
- 确定项目目标可行性
- 团队成员间互相熟悉
- 与其它部门互相知晓
这个仪式标志着团队的成立,此时团队成员应该信心满满,磨刀霍霍...
技术选型
技术选型方面,曾经在文章
工具和技术选型 中有写过SPLSCM要素等,对于一个团队在做新项目的技术选型时,应该考虑至少以下几个方面:
- 项目背景、场景、周期及未来的需求规划
- 技术方案是否足够满足需求
- 团队成员技术能力和接受程度
一般产品会有预计的项目生命周期,有些项目是周期较短,希望快速上线并可能很快就会失效下线,如一般线上推广活动、临时性的支持项目等,对于这种项目,技术选型时可能更多的是简单快速有效,不需要考虑长期的维护成本;而对于一些中长期的项目,需要考虑的问题则会更多一些:
- 团队成员变动风险,未来团队规模的扩展
- 团队成员开发习惯,开发流程规范
- 团队角色的划分,专业能力水平
- 相关技术及工具的生态是否足够完整、成熟
- 相关社区的支持情况及活跃程度
- 业务规模、复杂度
以下是几个我认为较重要的:
- 向技术标准和规范看齐,如前端的W3C规范,ECMAScript等,在满足项目可用性的前提下,支持标准就是支持未来,对以后的技术方案升级友好
- 保持简单、有序和可扩展,简单不是功能缺失,而是够用、恰好,控制信赖;有序是直观、易猜测和符合直觉,从而控制工程实现复杂度,提高可维护性
- 做好团队成员的培训,确保对技术的掌握和项目架构的设计理解一致
项目总是不断变化发展的,技术选型也可能不止在初期需要,随着需求的发展和变化,可能随时需要做出调整、改变。但初期的选型可以尽量避免一些调整,或者让后期的调整少一些负担、多一些灵活空间。
无论怎样,技术选型应该是非常重要的,虽然可能一般团队中都是Boss直接拍板或由资深成员直接决定,但比较好的流程是:
- 由产品或Boss对项目背景、需求场景等情况做详细的阐述
- 大家进行进行技术调研并准备提案,邀请各资深同事进行把关
- 选出几个方案进行对比权衡、多方论证,并记录问题和风险
- 选定方案后,制定实施计划
工程相关
技术方案确定后,接下来就是实施阶段了:
- 准备基础工程,建立仓库,分配权限
- 准备测试及正式环境
- 确定协作流程,包括分支管理策略、发布部署流程等
- 确定代码规范、工程约定等
- 确定一个迭代节奏,制定阶段目标
- 分解需求,分配任务...
除此之外,还应该建立项目Wiki,这对一个长期项目的技术传承可以起到非常重要的作用。应当鼓励和引导大家随时补充完善项目Wiki, 更新项目产品和设计文档、接口文档、设计实现思路等。
框架设计理念
- 理想的架构应该是新人照着原有的业务逻辑“依葫芦画瓢”就能开发业务,“顺藤摸瓜”就能搞明白整个架构
- 初次接触代码时,不需要查询过多的文档,或可以非常容易的查到相关文档,从而理解代码,并能马上开发类似模块
- 组件封装和使用具备一致性,可以按照直觉使用
- 什么是好的代码?提测后,bug可以迅速定位并解决,面对需求变更友好,局部重构优化更方便;
- 好的设计是会让项目越做越快,因为可以轻易复用代码,未来的需求都是基于此实现
时间是检验一个项目架构设计的最好工具,一个设计良好的架构可以保持良好的灵活性和扩展性,即使在经过各种的需求变化之后。
基础工程内容
整个项目工程就好比是一个生产车间,或者工地,以后我们就围绕它来进行需求的开发。因此通常我们都不太愿意每天面对一个脏乱差的环境,所以为提高开发效率和体验,基础工程中也应该面向开发者友好。
工程运行环境
一般项目都会分开发、测试和正式环境,我们根据需要,还添加了开发预览(nightly)和预发布(staging)环境,不同环境会默认连接不同的后端API接口类型:
环境 | 后端API | 地址 | 说明 |
dev | test | http://localhost:3000 | 本地开发环境,npm run dev |
nightly | test | - | 提PR自动部署到此环境,亦可手动部署 |
test | test | - | 手动部署到test环境,供验收和测试之用 |
staging | online | - | 接入线上接口数据,供回归测试之用,npm run staging |
production | online | - | 线上正式环境 |
连接两种后端API接口是自动完成的,项目运行时会自动检测环境并选择接口类型。
为方便开发调试,在本地也可连接线上接口:npm run staging
。
在不同环境下运行时,程序中都可以通过process.env获取当前环境信息:
console.log(env: ${process.env.BUILD_ENV} version: ${process.env.__version__} hash: ${process.env.__hash__} build: ${process.env.__build__} update: ${process.env.__update__}
)
同时程序会在控制台中打印,以及在非正式环境的页面中显示环境标记,方便在各环境中随时查看。
代码分支管理
分支主要分为:
- 发布分支(master)
- 主开发分支(develop)
- 其它特性分支(
feature-*
) - 修复分支(
fix-*
,hotfix-*
)
一般情况下,一个需求点为一个特性分支,一个大分支版本可以再分;分支管理的重点在于需求的划分及执行的方式。
团队中应该至少有一个对Git较为了解,以足以应对一些分支合并中的不策
任务集成
项目编译打包采用Webpack及一些Shell脚本,与一般项目差不太多,会自动化完成:
- 代码检查、编译、混淆优化、打包等
- 开发时的热更新
- 对于图片等资源文件的优化
- 自动生成svg sprite,管理图标
- 单元测试和e2e测试
- 不同环境调试运行
确保新人加入项目后,在node环境下可以三步即可运行项目:1)拉代码, 2)装依赖, 3)运行
使开发过程流畅,不需要频繁刷新页面,同步检查代码规范,自动修复和及时提示。
优化开发体验,就是提高效率,保持好心情
注释和文档
- 必要的业务逻辑添加必要的注释
- 一些后端接口的调用前添加接口文档链接地址或说明
- 较大/较复杂的模块设计需要有文档描述
- 与其它业务部门关联的业务、记录等
团队Wiki应该是大家共同维护的,不仅是团队项目信息的整理汇总,也是团队成果的展示平台
项目依赖升级
项目依赖采用最新稳定版本,并随时关注保持更新和升级,接入
Greenkeeper 后会自动提PR提示更新,但一些主版本号更新的依赖,还是需要手动check的。
这样做固然会需要付出一些成本,因为即使依赖不更新项目本亦可稳定运行,但保持项目依赖的更新会带来以下优点:
- 潜在bug会即时得到修复
- 性能可能会有所提升
- 引入新的特性
- 保持与社区主流版本的跟进
- 不至于造成技术脱节,以后升级困难
- 易于团队成员的学习成长,及招聘
流程管理
开发流程
简化开发流程,让开发更加关注,除了通过自动化完成一些任务之外,还要建立一些标准化流程规范,如:
- 需求评审、设计评审
- 开发任务跟踪、记录和管理
- 代码Review,分支合并规范
- 项目测试、验收流程规范
- 线上紧急修复预案
部署流程
理想情况下,开发完成并提交PR后,触发ci及代码格式检查,然后通过自动CodeReview和人肉CodeReview并Merged到主开发分支后,自动部署到nightly环境,接下来可手动触发依次部署到test,staging环境进行提交测试,最后将通过测试后的版本发布到线上正式环境。
特殊情况下,如紧急修复线上问题,可执行hotfix部署流程,代码合并到master分支后,直接部署上线。
以上自动化流程中,开发者只需要提交代码即可,其它工作诸如 自动标记版本,合并分支都会自动完成;同时hotfix流程也会自动将代码同步合并到主开发分支和线上分支。
代码Review
在每次提交PR同时会发起Code Review,此时会自动跑CI和
Codacy,大部分的代码规范会由Codacy自动发现并提交Review评论,还是非常方便的;剩下的人肉:
- Focus On
- 减少潜在bug
- 代码安全性
- 知识分享
- 代码质量提高
- 代码性能提升
- 及时有效的沟通
- Checkpoints
- 方案可行性
- 测试充分性
- 代码可读性
- 命名识别度
- 模块合理划分
- 代码整体结构优美
- 必要的注释信息
- 代码健壮性
- How To Do
- PR一般对应于一个issue
- 提交的PR信息中应该包含此次PR的描述
- PR 命名要具有较好可辨识性,便于搜索查阅
- 如果遇到PR合并冲突,需要尽快解决冲突
迭代Review
团队的阶段性回顾,是团队自省和自我完善的途径。通常在这时候,团队所有成员会一起:
- 回顾上一阶段完成的任务,未完成的目标
- 对流程和规范进行Review,不断优化调整
- 制定下一阶段的目标和计划
这个流程标志着团队的进步,此时团队成员应该信心满满,磨刀霍霍...
最后
归根结底,其实项目最重要的还是“人”。流程、规范都只是作为补充,但如果团队中“人”无法保证,流程、规范则可最大限度地确保项目稳健进行。