如何冻结 npm 依赖?
yarn
: 执行yarn
命令后默认会生成一份yarn.lock
文件,之后的npm
包版本安装都会遵照yarn.lock
中的版本描述(在执行yarn
、yarn update
、yarn add
、yarn remove
之后会自动将package.json
的依赖变动更新到yarn.lock
中)npm
: 执行npm shrinkwrap
命令后生成一份npm-shrinkwrap.json
文件,之后的npm
包版本安装都会遵照npm-shrinkwrap.json
的版本描述;而从npm
5.x 版本开始,执行npm install
命令之后默认会生成一份package-lock.json
文件,作用与npm-shrinkwrap.json
相同(在执行npm install
、npm update
之后会自动将package.json
的依赖变动更新到package-lock.json
或npm-shrinkwrap.json
中)- 直接在
package.json
中指定具体的依赖版本
依赖冻结与不冻结的优劣
冻结依赖:
- 可以保证开发、测试和线上的依赖一致,避免由于三方包依赖不一致而引入的 bug
- 可以缩短测试周期,加速上线
- 缺点:难以发现某版本依赖的潜在 bug,对于比较滞后的版本依赖,升级成本较高
不冻结依赖:
- 可以保证依赖的版本是较新的版本,某些低版本的依赖存在的潜在 bug 可以通过自动升级解决
- 可以减少手动升级带来的成本
- 缺点:需要依赖靠谱的三方包,测试周期长
Q & A
Q: 如何判断一个
npm
包是靠谱的?
A: 高质量的npm
包一般有以下几个特征:- 版本为 1.x 以上的稳定版本
- 版本更新遵循
semver
语义化 - 有较大的下载量
- github star 数量多
- 文档说明比较完善
- 测试覆盖率和通过率高,最好都是 100%
- 维护者的知名度高
- github issue 处理效率高
Q: 如何解决不冻结依赖时,开发、测试和线上的代码打包依赖不一致的问题?
A: 最佳解决方案是保证测试和线上使用的包是同一份包。但在有些 case 下需要额外处理,比如对于使用了github flow
开发流程,往往是测试时候在 a 分支打包,而最后上线的时候会将 a 分支合并到 master 分支,然后重新打包部署,这个时候需要测试人员重新对合并后的 master 新包做一次回归测试方可发上线,这种做法带来的负面影响是会导致测试周期增加Q: 采取冻结依赖方式带来的升级成本过高如何处理?
A: 一旦项目采取了冻结依赖的方式,后续升级会带来很多的风险,建议定期升级,然后对升级后的包进行回归测试Q: 有些‘冷门’的功能,可能无法找到靠谱的包,不冻结依赖如何处理这种 case?
A: 使用不冻结依赖的前提是项目引入的依赖是靠谱的,如果遇到了题述的 case,有两种解决方案:- 1.简单的功能可以自己手写实现
- 2.如果想引用一些不靠谱的包,在
package.json
中指定该包的具体版本
Q: 使用依赖冻结的方式,
package-lock.json
,yarn.lock
,npm-shrinkwrap.json
文件是否该提交到 git 仓库中?
A: 建议提交。对于多人开发的系统,提交版本冻结描述文件可以保证使用的版本一致性并且方便依赖的重建