为什么“npm安装”要重写package-lock.json?

我最近刚升级到[email protected]。我现在有了一个package lock.json文件,其中包含了package.json中的所有内容。我希望,当我运行npm install时,会从锁文件中提取依赖项版本,以确定应该在我的节点模块目录中安装什么。奇怪的是,它实际上最终修改和重写了我的package lock.json文件

例如,锁文件的typescript指定为版本2.1.6。然后,在执行npm install命令后,版本更改为2.4.1。这似乎违背了锁文件的全部目的

我错过了什么?如何让npm真正尊重我的锁文件

更新3:正如其他答案所指出的,npm 5.7.0中引入了npm ci命令,作为在ci上下文中实现快速和可复制构建的额外方法。有关更多信息,请参阅文档和npm博客


更新2:更新和澄清文档的问题是GitHub问题#18103


更新1:以下描述的行为在npm 5.4.2中得到修复:当前预期的行为在GitHub发行版17979中概述


原始答案:在npm 5.1.0中,package lock.json的行为发生了更改,如16866期所述。从5.1.0版开始,npm显然有意采用您观察到的行为

这意味着只要在package.json中找到依赖项的较新版本,package.json就可以覆盖package lock.json。如果您想有效地固定依赖项,现在必须指定不带前缀的版本,例如,您需要将它们写成1.2.0,而不是~1.2.0^1.2.0。然后,package.jsonpackage lock.json的组合将产生可复制的构建。需要明确的是:package lock.json不再单独锁定根级别的依赖项

这一设计决策是否正确还值得商榷,由于GitHub在17979号问题上的混乱,目前正在进行讨论。(在我看来,这是一个值得怀疑的决定;至少名称lock不再适用。)

还有一个补充说明:对于不支持不可变包的注册中心,也有一个限制,例如当您直接从GitHub而不是npmjs.org提取包时。有关更多说明,请参阅此包锁文档

发表评论