npm中package-lock的resolevd冲突

前言

上次讲到用package-lock锁版本来保证项目的一致性和稳定性。但在使用过程中,发现同一项目的不同开发,在install安装依赖之后,package-lock.json文件会出现冲突,下面将针对这些问题进行探究和解决。

一、合分支时由于版本不同造成的冲突

简而言之,就是两个开发人员安装了不同版本的新npm包,lock文件不同,从而导致的冲突。这类都属于应有的冲突,只要由merge人员核对版本号,选择正确的版本,统一项目的lock版本即可。

二、package-lock中的resolve字段被不同环境的npm registry改写,从而导致的很多冲突

这也是此次要探究的重点。明明版本号都是相同的,但是对应资源的下载地址不同,合分支时出现了很多的冲突。

1、resoled含义

从官网npm配置可知,resolved字段表示相对于仓库源registry的一个包下载地址。如果这个包的下载地址和仓库源不在同一服务上,那么这个地址会是一个绝对路径。

(在项目中,发现有的包,如【npx】包下面的依赖项的resolved值为false,安装发现,直接安装npx此包,就包含了所有的下级依赖项(因此会比一般的tgz文件大,有5M,一般只会有7K。),所以可能下级依赖项的resolved值为false,不会再根据下级依赖包再去安装。)

2、出现冲突的原因及解决方式

(1)本地registry的配置不同,如有的是淘宝镜像,有的是公司的等等。

本地registry的配置不同,会导致install时package-lock.json被改写,造成冲突。所以为了规避这个问题,需要在团队内统一npm registry,可以在项目根目录中使用.npmrc配置文件来配置项目级别的registry来进行统一。
如在his中的.npmrc

registry=http://npm.guahao-inc.com

(2)环境及npm和node版本不同

据反馈,在不同电脑上,由于npm和node,操作系统的不同,即便在项目里设置了统一的.npmrc配置,在项目中执行npm install之后,package-lock.json文件会有些不同:
发现某些子依赖项的resoled:false,可能会换成“”空字符串,甚至换成url地址,造成冲突,还有就是可能增加optional字段,前者如上文所述,false替换为“”不会造成问题,因为都是不会再去重新下载子依赖。


示例:log-update这个包,是一个父依赖包和子依赖包都有resoled地址的,下载发现,父依赖包链接只会下载父依赖,他的所有子依赖会根据对应的resoled字段再去下载;而npx这个包,子依赖resolve的字段为false或“”,根据父依赖地址安装会发现其实已经安装了所有的子依赖,所以resoleced字段为false。

由于缺少官方说明,为了重现和避免此类问题,我做了如下调研比对

对比node和npm版本

统计了团队内大家的node和npm版本情况,核查对应情况,在不删除lock文件前提下,不同条件下分别执行install,结果如下

电脑 npm版本 node 版本 npx包子依赖的resolved值
mac 6.4.1 10.12.0 false
mac 6.4.1 10.15.3 false
mac 6.4.1 10.16.0 false
mac 6.13.4 10.15.3 false
mac 6.14.4 10.15.3 false
mac 6.7.0 11.13.0 false
windows 6.13.4 10.15.3 ""和url并存
windows 6.7.0 11.14.0 ""和url并存
windows 6.13.4 11.14.0 ""和url并存
初步结论

通过比对不同系统和npm及node版本在install npx这个包的情况:

1、mac下常用的node和npx版本在install之后,lock文件无差别,子依赖resolved字段内容为false

2、windows下常用的node和npx版本在install之后,lock文件无差别,子依赖resolved字段内容为“”或url地址。

可以初步得出,package-lock文件中存在的resolved的字段不一致,在同一系统和同一编辑器内不会出现,与常用的npm及node版本无关,可能是windows和mac系统下不同编辑器对resolved字段解析为“”或false的方式不同。

另:

删掉lock文件,后续的npx包install安装时,子依赖没有了resoleved字段(即为“”,为false,都是没有这个字段,而是bundled: “true” . (表示在父依赖中已绑定安装此子依赖),mac和windows统一。

三、解决方案

1、使用工具自动合并lock文件冲突

对于两个不同install生成的lock文件,合并分支时发生冲突,npm官方做出了一定解释并提供了一个专门用于自动合并lock文件冲突的工具:npm-merge-driver,这个工具设置的算法会合并两个分支的所有依赖树,综合成一个新的lock文件。

此方法亲测可行有效,在install时对于lock文件的冲突,会自动合并,能帮助开发者一键解决lock文件的冲突。

! 但此方式并没有彻底解决mac和Windows(也可能是编辑器差异)导致的resolved:“”和false不同的问题。lock文件统一后,在mac中install,原本统一的resolved:""依旧会更新为false。(不过“”和false起到的是一样的作用,不影响代码)

2、统一大版本node及npm,删除原有resolved:false或“”的依赖包,重新install。

追本溯源,出现resolved:"false"和resolved: ''差异的依赖包,其实是子依赖已经bundled进父依赖的依赖包,从而子依赖的下载源为false或“”,因而针对bundled的npm依赖包,如npx,可以删除古早的这个npx依赖包,重新install。这样,package-lock文件会重新更新,原有的resoleved字段不再展示,而是展示一个“bundled: “true”的字段”。

此方式更新过lock文件后在mac和windows下重新install都不会再出现冲突。由官网有关resoleved和bundled所述:对于bundled的依赖,不会再包含resolved字段和integrity字段,这可以完全解决当下的冲突问题。

考虑到npm和node版本不同,还有可能导致增加optional字段(true可选,false不可选),因而最好统一node和npm的大版本

总结

对于resoled的冲突,解决方式如下

  1. 统一配置项目.npmrc中的registry地址
  2. 对于bundled的依赖,如npx,最好重新安装,避免resolved字段差异(推荐)
  3. 对于lock文件冲突,如一时难以手动确认合并方式,推荐使用npm-merge-driver
  4. 建议统一node及npm大版本,目前已测可行为:node >10.15.3 npm >6.13.4

附录:参考

npm官方文档

简书:registry统一

你可能感兴趣的:(【前端】npm及webpack,npm,package-lock)