协慌网

登录 贡献 社区

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

我最近才升级到npm @ 5 。我现在有一个package-lock.json文件,其中包含package.json 中的所有内容。我希望当我运行npm install ,将从锁定文件中提取依赖项版本,以确定应该在我的node_modules目录中安装什么。奇怪的是,它实际上最终修改并重写了我的package-lock.json文件。

例如,锁定文件已将打字稿指定为版本2.1.6 。然后,在npm install命令之后,版本更改为2.4.1 。这似乎破坏了锁定文件的全部目的。

我想念什么?如何使 npm 真正尊重我的锁定文件?

答案

更新 3:正如其他答案所指出的那样, npm ci命令,作为在 CI 上下文中实现快速且可复制的构建的附加方法。有关更多信息,请参见文档npm 博客。


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


更新 1:以下描述的行为已在 npm 5.4.2 中修复: GitHub 问题#17979 中概述了当前预期的行为。


原始答案: package-lock.json的行为在 npm 5.1.0 中已更改,如问题#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 提取软件包时。有关更多说明,请参见此软件包锁文档。

我发现会有一个新版本的 npm 5.7.1和新命令npm ci ,它将仅从package-lock.json

新的 npm ci 命令仅从锁定文件安装。如果您的 package.json 和锁定文件不同步,则它将报告错误。

它的工作原理是丢弃您的 node_modules 并从头开始重新创建它。

除了保证您仅获得锁定文件中的内容外,如果不使用 node_modules 进行安装,它的安装速度也比 npm 安装要快得多(2x-10x!)。

您可能会从名称中得知,我们希望它对持续集成环境大有裨益。我们还希望从 git 标签进行生产部署的人们会从中受益匪浅。

使用新推出的

npm ci

npm ci 承诺将为大型团队带来最大的利益。使开发人员能够 “退出” 软件包锁定功能可以促进大型团队之间更有效的协作,并且完全安装锁定文件中的内容的功能可以每月节省数十甚至数百个开发人员的时间,从而释放团队花更多的时间来建造和运送令人惊奇的东西。

引入npm ci以实现更快,更可靠的构建