本文会分享一下代码复用方面的心得,且对当前项目中的实践做一下介绍。
通过代码复用至少可以达到两个目的
- 建设团队可复用资产,以实现减少开发时间,提高代码质量
- 通过对可复用代码的生成和维护,提高个人和团队技术水平
本文包括以下三部分
- 对代码复用相关的理解和资料
- 当前常见的可复用方式和使用情况
- 维护好文档,使代码复用更易上手
代码复用相关参考
复用相关的方法论较多且意见不一,这里只会大概说一下自己的所知和推荐一下参考资料。
对于代码复用整体可参考art-of-software-reuse。
抽象
当我们对代码进行封装时,就要先进行抽象,即隐藏不必要的部分,从而更清晰的展示真正需要的部分。
关于抽象,有个很有名的原则,即DRY (an acronym for "Don't Repeat Yourself"),但是一个功能一开始不太能预见将来会以什么形式复用,因此我们可以接受一定程度的重复,毕竟重复比不好的抽象要好,比如为了复用不断添加参数和条件语句导致很难维护。
至于什么时候开始准备复用,有种说法是第三次重复时可以考虑重构为复用,具体还是根据具体情况。
- What is abstraction; why is it useful in software engineering? quora 上一个问题
- Goodbye, Clean Code Dan 对 DRY 的看法
- The Wrong Abstraction
prefer duplication over the wrong abstraction出处 - What Are Abstractions in Software Engineering with Examples 对抽象的具体解释
- Rule of three 三原则,用来说明什么时候开始从重复开始复用
- 设计模式 一本很有名的书
重构
无论一开始多么精心设计,后续复用时总会出现不满足的情况,因此要在测试充分的情况下不断进行重构迭代,而不是通过增量方式导致最终无法维护。
通过重构可以使代码更容易理解。
- 重构 第二版
code review 和沟通
保证可复用代码的质量和互相学习。
文档
明确可复用代码的用途和使用方法,参考。
代码复用方式
本地依赖
这里按有没有版本管理分为两种
引入版本管理前
即通过yarn link在一个项目中利用symlink使用另一个本地包。
另一个方式是使用 monorepo,常见的是lerna和yarn workspace,这个组合也是项目中实际使用的。
lerna是yarn这类工具的封装,早期在实现 monorepo 时是下载完对应依赖后再根据引用创建对应的symlink,后来yarn直接内置了这个功能,因此基础的 monorepo 不需要lerna也能完成,但是lerna封装了更多可能有用的功能。
如果利用 monorepo 将依赖和正常迭代分支一起维护发布,也能完成基本功能,但如果可复用代码涉及到多个仓库,就会出现问题,比如自动化发布时无法获取依赖。
引入版本管理后
即通过 npm 包的方式进行管理,将对应 npm 包下载到本地。
实际的项目中使用的是GitHub Packages,其中鉴权需要personal access token (PAT),获取步骤参考这里。
代码发布前要做好以下部分
- 单元测试
- changelog
- 执行
yarn build使用gulp对代码进行转换。
为了更好的维护 npm 包,保证发布的顺序,这里采用的是利用单独分支管理可复用代码的迭代,版本号参考Semantic Versioning。
在线依赖
使用本地依赖时每次更新代码时需要重新打包发布,在线依赖可以避免不必要的打包,目前在使用的包括两种方式
- 利用接口提供对应数据,比如strapi。
- 利用Module Federation,这种实现的版本管理实际上没有利用到,可在 a/b test 功能上先使用。
文档
文档是代码的说明书,这里使用的是dumi,目录结构按照 dumi 的约定,和 npm 包在同一分支迭代、
其主要完成了以下功能
- 使用 markdown 自动生成文档网页,通过演示 demo 使代码复用更清晰。
- 利用 ts 注释,自动生成组件 api(并没有很智能,必要情况下还是要手写,比如 interface 无法进一步生成说明)