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

新手上路,请多包涵

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

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

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

原文由 Viper Bailey 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.5k
2 个回答

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


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


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


原始答案(5.4.2 之前): package-lock.json 的行为在 npm 5.1.0 中已更改,如 问题 #16866 中所述。您观察到的行为显然是 npm 从 5.1.0 版开始的。

这意味着 package.json 可以覆盖 package-lock.json 每当找到新版本的依赖项时 package.json 。如果您想有效地固定您的依赖项,您现在必须指定不带前缀的版本,例如,您需要将它们写为 1.2.0 而不是 ~1.2.0^1.2.0 。然后 package.jsonpackage-lock.json 的组合将产生可重复的构建。要清楚: package-lock.json 单独不再锁定根级别的依赖关系!

这个设计决定是否好是有争议的,在 GitHub 上的 问题 #17979 中,这种混乱导致了持续的讨论。 (在我看来,这是一个值得商榷的决定;至少 lock 这个名字不再适用了。)

另一个注意事项:对于不支持不可变包的注册表也有限制,例如当您直接从 GitHub 而不是 npmjs.org 拉包时。有关进一步说明,请参阅 此包锁文档

原文由 jotaen 发布,翻译遵循 CC BY-SA 4.0 许可协议

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

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

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

除了保证您只会获得锁定文件中的内容之外,当您不从 node_modules 开始时,它也比 npm install 快得多(2x-10x!)。

顾名思义,我们希望它对持续集成环境大有裨益。我们还希望从 git 标签进行生产部署的人们会看到重大收益。

原文由 Ivan Shcherbakov 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题