为什么“npm install”重写package-lock.json?

我刚刚升级到npm @ 5。 我现在有一个package-lock.json文件,包含package.json的所有内容。 我期望,当我运行npm install ,依赖版本将被从locking文件中拉出,以确定应该安装在我的node_modules目录中。 奇怪的是,它实际上最终修改和重写我的package-lock.json文件。

例如,locking文件的打印机指定为版本2.1.6。 然后,在npm install命令之后,版本更改为2.4.1。 这似乎打败了锁文件的整个目的。

我错过了什么? 我如何获得npm来尊重我的locking文件?

package-lock.json的行为在npm 5.1.0中被修改,如#16866中讨论的那样 。 您观察到的行为显然是由版本5.1.0的npm所打算的。

这意味着package.json只要在package.jsonfind一个依赖关系的更新版本就可以package-lock.json 。 如果你想有效地固定你的依赖关系,你现在必须指定没有前缀的版本,这意味着你需要把它们写成1.2.0而不是~1.2.0^1.2.0 。 然后, package.jsonpackage-lock.json的组合将产生可重复的构build。 要清楚的是: package-lock.json本身不再locking根级别的依赖关系!

无论这个devise的决定是否好,都是有争议的,因此在Github的问题#17979上引起了这个混淆。 (在我看来,这是一个值得怀疑的决定,至less名字lock不再是真实的。)

还有一点需要注意的一点是,对于不支持不可变包的registry也有一个限制,比如当你从Github而不是npmjs.org直接拉包时。 有关进一步说明,请参阅封装锁的文档 。


更新:上面描述的行为在npm 5.4.2中得到修复:目前的预期行为在Github issue#17979中概述。

你可能有这样的东西:

 "typescript":"~2.1.6" 

在你的package.json中npm更新到最新的次要版本,你的情况是2.4.1

编辑:从OP的问题

但是这并不能解释为什么“npm install”会更改locking文件。 locking文件是否意味着创build可重复的构build? 如果是这样,不pipe什么样的价值,它仍然应该使用相同的2.1.6版本。

回答:

这是为了locking完整的依赖关系树。 假设typescript v2.4.1需要typescript v2.4.1 。 当你npm安装它抓取widget v1.0.0 。 稍后,你的开发人员(或CI构build)进行npm安装并获取typescript v2.4.1widget已经更新到widget v1.0.1 。 现在你的节点模块不同步。 这是package-lock.json防止的。

或者更一般地说:

作为一个例子,考虑一下

包A:

{“name”:“A”,“version”:“0.1.0”,“dependencies”:{“B”:“<0.1.0”}}

包B:

{“name”:“B”,“version”:“0.0.1”,“dependencies”:{“C”:“<0.1.0”}}

和包C:

{“name”:“C”,“version”:“0.0.1”}

如果这些是registry中唯一可用的A,B和C版本,那么将安装一个正常的npm install A:

A@0.1.0 – B@0.0.1 – C@0.0.1

但是,如果发布B@0.0.2,则会安装一个新的npm安装程序A:

A@0.1.0 – B@0.2.2 – C @ 0.0.1假设新版本不修改B的依赖关系。 当然,新版本的B可以包含一个新版本的C和任何数量的新的依赖关系。 如果这样的改变是不希望的,那么A的作者可以指定对B0.0.1的依赖。 但是,如果A的作者和B的作者不是同一个人,那么A的作者根本就没有办法说B不改变C的新发布版本。


OP问题2:让我看看我是否理解正确。 你所说的是锁文件指定了次依赖的版本,但依然依赖于package.json的模糊匹配来确定最高层的依赖关系。 这是准确的吗?

答:不可以。package-lock会locking整个包树,包括package.json描述的根包。 如果package-lock.jsonpackage-lock.json被locking在2.4.1 ,它应该保持这种方式,直到它被更改。 并且可以说明天typescript发布版本2.4.2 。 如果我签出你的分支并运行npm install ,npm将会遵守这个lockfile并安装2.4.1

更多关于package-lock.json

对于npm修改node_modules树或package.json的任何操作,将自动生成package-lock.json。 它描述了生成的确切树,以便后续安装能够生成相同的树,而不pipe中间依赖性更新如何。

这个文件旨在被提交到源代码库,并提供各种用途:

描述依赖关系树的单一表示,以保证队友,部署和持续集成确保安装完全相同的依赖关系。

为用户提供一个工具,使其能够“前进”到先前的node_modules状态,而不必提交目录本身。

通过可读的源代码控制差异来促进树更改的更大可见性。

并通过允许npm跳过先前安装的软件包的重复元数据分辨率来优化安装过程。

https://docs.npmjs.com/files/package-lock.json

看来这个问题是固定在npm v5.4.2

https://github.com/npm/npm/issues/17979

(向下滚动到线程中的最后一个注释)

将来,您将能够使用--from-lock-file (或类似的)标志package-lock.json进行安装,而不进行修改。

这对于可重复构build非常重要的CI等环境很有用。

请参阅https://github.com/npm/npm/issues/18286来跟踪该function。;

一个简单的答案: package.json像往常一样拥有你的依赖关系,而package-lock.json是“一个确切的,更重要的可复制的node_modules树”(取自npm docs本身 )。

至于那个棘手的名字,它的NPM试图赶上纱。