本文会分享一下代码复用方面的心得,且对当前项目中的实践做一下介绍。
通过代码复用至少可以达到两个目的
- 建设团队可复用资产,以实现减少开发时间,提高代码质量
- 通过对可复用代码的生成和维护,提高个人和团队技术水平
本文包括以下三部分
- 对代码复用相关的理解和资料
- 当前常见的可复用方式和使用情况
- 维护好文档,使代码复用更易上手
代码复用相关参考
复用相关的方法论较多且意见不一,这里只会大概说一下自己的所知和推荐一下参考资料。
对于代码复用整体可参考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 无法进一步生成说明)