前言
最近在项目中遇到本地跑的代码没问题,而通过jenkins打包丢到线上却出现bug的情况。经过一番排查,发现问题出在了项目版本依赖没锁定,由于我们的项目没有上传package-lock.json导致通过jenkins安装的依赖和本地依赖不一致导致bug的产生。
package-lock.json
那么我们是否要把package-lock.json上传到git存储库呢?
答案是要!
首先看看官方的解释:
链接:docs.npmjs.com/cli/v6/conf…
官方提到我们应该将
package-lock.json上传到存储库中,用来保证团队成员、部署和持续集成安装完全相同的依赖。同时提示我们不应把package-lock.json推送到npm库中,因为它只在最顶层生效(你推到npm库也没用哈)。在npm@5.4.2版本后,npm主要有以下表现:
- 1、 无package-lock.json
npm i根据package.json进行安装,并生成package-lock.json - 2、package.json和package-lock.json的
版本不兼容npm i会以package.json会更新package-lock.json的情况为,准进行安装,并更新package-lock.json - 3、package.json和package-lock.json的
版本兼容npm i会以package-lock.json为准进行安装。
由于上面第二个条件的限制,在某些情况下你更新了某个依赖的版本,这时可能出现更新package-lock.json的情况,如果这个行为是你主动发起的,你希望package-lock.json被更新,那么这么做是没有问题的。但有时我们在多人协作的时候可能出现某个人不小心更新了依赖的版本,而我们又不希望更新package-lock.json的情况,因为这可能会引发一些不可知的问题。针对这种情况,官方也给出了一些方案。比如使用npm ci,npm ci与npm i主要的差异有:
- 如果package-lock.json或npm-shrinkwrap.json中的依赖与package.json中不一致(即以上2的情况),
npm ci会报错并退出,而不是更新lock文件 npm ci只会安装整个项目,无法单独安装某个依赖项目- 如果项目中已有
node_modules,该文件夹会在npm ci执行安装前自动被移除 - 该命令不会写入package.json或lock文件,安装的行为是完全被固定的。
- 比
npm i快,比npm i快,比npm i快!!!!
基于以上的几种特性,使用npm ci能够有效的锁定版本,同时不更新package-lock.json文件。它比npm i 更严格,用于线上、测试环境也会更安全
由于我们的项目使用的是lerna来管理多个模块,而lerna bootstrap命令在ci的环境下默认就是使用npm ci来安装版本依赖。
因此对于我们项目的bug,解决方法如下:
方案一
把之前在本地生成的package-lock.json上传到git,jenkins打包时通过lerna bootstrap也就是npm ci去安装依赖,这样能保证线上的依赖和本地的依赖安装一致,不会出现莫名其妙的bug
方案二
直接写死版本号,不适用package-lock.json,比如"vue": "2.6.11",需要升级某个包的版本的话就手动去更改版本号升级。其实这样子写是有缺陷的,官方说如果你依赖项中的某个依赖项发布了新的版本,即使你在最外面使用固定的依赖项"vue": "2.6.11",里面的依赖变成2.7.0的话,vue也会更新为2.7.0。(不推荐)
yarn.lock
包管理工具yarn的yarn.lock 文件会申明具体的请求地址,具体的版本号,甚至 sha 值(怕别人修改已有包)。 但是 yarn.lock 文件可以保证不管几次安装, 安装的依赖都是一样的。所以yarn的官方文档是建议把yarn.lock上传到git上面的
文档地址: yarnpkg.com/getting-sta…
pnpm-lock.yaml
同上。
题外话
有些同学可能习惯使用cnpm,因为安装速度确实比npm快不少,但在版本依赖锁定方案中,最基础的一条就是:不要使用cnpm,因为cnpm,是不支持依赖版本锁定的。
也就是说,无论你的项目中有package-lock.json、npm-shrinkwrap.json还是yarn.lock文件,执行cnpm i安装依赖的时候他们都只是摆设,都只会根据package.json文件进行安装。所以通过cnpm安装依赖是不能避免上面问题的。而且有很多网友反馈cnpm会有依赖包丢失的问题。
但是使用npm避不开的一个问题就是安装速度,实在太慢了。这里我们可以通过手动更换npm源和nrm的方式实现使用npm命令的同时,依然享受cnpm的安装速度。
当然还是建议直接使用pnpm或者yarn包管理工具,这两个工具的下载速度都比npm要快很多!