本文翻译自:Why does “npm install” rewrite package-lock.json?

I just recently upgraded to npm@5. 我最近才升级到npm @ 5。 I now have a package-lock.json file with everything from package.json. 我现在有一个package-lock.json文件,其中包含package.json中的所有内容。 I would expect that, when I run npm install that the dependency versions would be pulled from the lock file to determine what should be installed in my node_modules directory. 我希望当我运行npm install ,将从锁定文件中提取依赖项版本,以确定应该在我的node_modules目录中安装什么。 What's strange is that it actually ends up modifying and rewriting my package-lock.json file. 奇怪的是,它实际上最终修改并重写了package-lock.json文件。

For example, the lock file had typescript specified to be at version 2.1.6. 例如,锁定文件的打字稿指定为版本2.1.6。 Then, after the npm install command, the version was changed to 2.4.1. 然后,在npm install命令之后,版本更改为2.4.1。 That seems to defeat the whole purpose of a lock file. 这似乎破坏了锁定文件的全部目的。

What am I missing? 我想念什么? How do I get npm to actually respect my lock file? 如何让npm真正尊重我的锁定文件?


#1楼

参考:https://stackoom.com/question/32uI4/为什么-npm-install-会重写package-lock-json


#2楼

You probably have something like: 您可能有类似以下内容:

"typescript":"~2.1.6"

in your package.json which npm updates to the latest minor version, in your case being 2.4.1 在您的package.json ,其中npm更新为最新的次要版本,在您的情况下为2.4.1

Edit: Question from OP 编辑:OP的问题

But that doesn't explain why "npm install" would change the lock file. 但这并不能解释为什么“ npm install”会更改锁定文件。 Isn't the lock file meant to create a reproducible build? 锁定文件不是要创建可复制的版本吗? If so, regardless of the semver value, it should still use the same 2.1.6 version. 如果是这样,则无论semver值如何,都应仍使用相同的2.1.6版本。

Answer: 回答:

This is intended to lock down your full dependency tree. 这旨在锁定您的完整依赖关系树。 Let's say typescript v2.4.1 requires widget ~v1.0.0 . 假设typescript v2.4.1需要widget ~v1.0.0 typescript v2.4.1 When you npm install it grabs widget v1.0.0 . 当您安装npm时,它会获取widget v1.0.0 Later on your fellow developer (or CI build) does an npm install and gets typescript v2.4.1 but widget has been updated to widget v1.0.1 . 稍后在您的其他开发人员(或CI构建)上进行npm安装并获取typescript v2.4.1widget已更新为widget v1.0.1 Now your node module are out of sync. 现在,您的节点模块不同步。 This is what package-lock.json prevents. 这就是package-lock.json防止的。

Or more generally: 或更笼统地说:

As an example, consider 例如,考虑

package A: 套餐A:

{ "name": "A", "version": "0.1.0", "dependencies": { "B": "<0.1.0" } } {“名称”:“ A”,“版本”:“ 0.1.0”,“依赖关系”:{“ B”:“ <0.1.0”}}

package B: 套餐B:

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

and package C: 和包C:

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

If these are the only versions of A, B, and C available in the registry, then a normal npm install A will install: 如果这些是注册表中可用的A,B和C的唯一版本,则将安装普通的npm install A:

A@0.1.0 -- B@0.0.1 -- C@0.0.1 A@0.1.0-B@0.0.1-C@0.0.1

However, if B@0.0.2 is published, then a fresh npm install A will install: 但是,如果发布了B@0.0.2,则将安装新的npm install A:

A@0.1.0 -- B@0.0.2 -- C@0.0.1 assuming the new version did not modify B's dependencies. A@0.1.0-B@0.0.2-C@0.0.1假设新版本未修改B的依赖关系。 Of course, the new version of B could include a new version of C and any number of new dependencies. 当然,新版本的B可以包括新版本的C和任何数量的新依赖项。 If such changes are undesirable, the author of A could specify a dependency on B@0.0.1. 如果不希望发生此类更改,则A的作者可以指定对B@0.0.1的依赖。 However, if A's author and B's author are not the same person, there's no way for A's author to say that he or she does not want to pull in newly published versions of C when B hasn't changed at all. 但是,如果A的作者和B的作者不是同一个人,则A的作者无法说当B完全没有变化时,他或她就不想插入新发布的C版本。


OP Question 2: So let me see if I understand correctly. OP问题2:所以让我看看我是否理解正确。 What you're saying is that the lock file specifies the versions of the secondary dependencies, but still relies on the fuzzy matching of package.json to determine the top-level dependencies. 您要说的是,锁定文件指定了二级依赖关系的版本,但仍依赖于package.json的模糊匹配来确定顶级依赖关系。 Is that accurate? 准确吗?

Answer: No. package-lock locks the entire package tree, including the root packages described in package.json . 答:不。package-lock锁定整个软件包树,包括package.json描述的根软件包。 If typescript is locked at 2.4.1 in your package-lock.json , it should remain that way until it is changed. 如果typescript在锁定2.4.1在您的package-lock.json ,直到它被改变了它应该保持这种方式。 And lets say tomorrow typescript releases version 2.4.2 . 并说明天typescript发布2.4.2版本。 If I checkout your branch and run npm install , npm will respect the lockfile and install 2.4.1 . 如果我签出您的分支并运行npm install ,则npm将遵守锁定文件并安装2.4.1

More on package-lock.json : 有关package-lock.json更多package-lock.json

package-lock.json is automatically generated for any operations where npm modifies either the node_modules tree, or package.json. 对于npm修改node_modules树或package.json的任何操作,都会自动生成package-lock.json。 It describes the exact tree that was generated, such that subsequent installs are able to generate identical trees, regardless of intermediate dependency updates. 它描述了生成的确切树,因此无论中间依赖项更新如何,后续安装都可以生成相同的树。

This file is intended to be committed into source repositories, and serves various purposes: 该文件旨在提交到源存储库中,并具有多种用途:

Describe a single representation of a dependency tree such that teammates, deployments, and continuous integration are guaranteed to install exactly the same dependencies. 描述依赖关系树的单个表示,这样可以确保队友,部署和持续集成安装完全相同的依赖关系。

Provide a facility for users to "time-travel" to previous states of node_modules without having to commit the directory itself. 为用户提供一种工具,使其可以“时间旅行”到node_modules的先前状态,而不必提交目录本身。

To facilitate greater visibility of tree changes through readable source control diffs. 为了通过可读的源代码控制差异更好地了解树的变化。

And optimize the installation process by allowing npm to skip repeated metadata resolutions for previously-installed packages. 并允许npm跳过先前安装的软件包的重复元数据解析,从而优化安装过程。

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


#3楼

Update 3: As other answers point out as well, the npm ci command got introduced in npm 5.7.0 as additional way to achieve fast and reproducible builds in the CI context. 更新3:正如其他答案所指出的那样,npm 5.7.0中引入了npm ci命令,作为在CI上下文中实现快速且可复制的构建的其他方法。 See the documentation and npm blog for further information. 有关更多信息,请参见文档和npm博客 。


Update 2: The issue to update and clarify the documentation is GitHub issue #18103 . 更新2:更新和澄清文档的问题是GitHub问题#18103 。


Update 1: The behaviour that was described below got fixed in npm 5.4.2: the currently intended behaviour is outlined in GitHub issue #17979 . 更新1:以下描述的行为已在npm 5.4.2中修复: GitHub问题#17979中概述了当前预期的行为。


Original answer: The behaviour of package-lock.json was changed in npm 5.1.0 as discussed in issue #16866 . 原始答案: package-lock.json的行为已在问题#16866中在npm 5.1.0中更改 。 The behaviour that you observe is apparently intended by npm as of version 5.1.0. 从5.1.0版开始,您观察到的行为显然是npm预期的。

That means that package.json can override package-lock.json whenever a newer version is found for a dependency in package.json . 这意味着,只要在package.json找到依赖项的较新版本, package.json就可以覆盖package-lock.json If you want to pin your dependencies effectively, you now must specify the versions without a prefix, eg, you need to write them as 1.2.0 instead of ~1.2.0 or ^1.2.0 . 如果要有效固定依赖项,则现在必须指定不带前缀的版本,例如,您需要将它们写为1.2.0而不是~1.2.0^1.2.0 Then the combination of package.json and package-lock.json will yield reproducible builds. 然后, package.jsonpackage-lock.json的组合将产生可复制的构建。 To be clear: package-lock.json alone no longer locks the root level dependencies! 需要明确的是:仅package-lock.json不再锁定根级别依赖项!

Whether this design decision was good or not is arguable, there is an ongoing discussion resulting from this confusion on GitHub in issue #17979 . 不管这个设计决定是好的还是不可行的,在GitHub上的问题#17979上一直在进行讨论。 (In my eyes it is a questionable decision; at least the name lock doesn't hold true any longer.) (在我看来,这是一个值得商decision的决定;至少名称lock不再适用。)

One more side note: there is also a restriction for registries that don't support immutable packages, such as when you pull packages directly from GitHub instead of npmjs.org. 还有一点注意事项:对于不支持不可变软件包的注册表也有一个限制,例如当您直接从GitHub而不是npmjs.org提取软件包时。 See this documentation of package locks for further explanation. 有关进一步的说明,请参阅此包锁文档 。


#4楼

It appears this issue is fixed in npm v5.4.2 看来此问题已在npm v5.4.2中修复

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

(Scroll down to the last comment in the thread) (向下滚动到线程中的最后一条注释)

Update 更新资料

Actually fixed in 5.6.0. 实际在5.6.0中已修复。 There was a cross platform bug in 5.4.2 that was causing the issue to still occur. 5.4.2中存在一个跨平台错误,导致该问题仍然存在。

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

Update 2 更新2

See my answer here: https://stackoverflow.com/a/53680257/1611058 在这里查看我的答案: https : //stackoverflow.com/a/53680257/1611058

npm ci is the command you should be using when installing existing projects now. npm ci是您现在安装现有项目时应使用的命令。


#5楼

In the future, you will be able to use a --from-lock-file (or similar) flag to install only from the package-lock.json without modifying it. 将来,您将能够使用--from-lock-file (或类似的)标志仅从 package-lock.json安装而不进行修改。

This will be useful for CI, etc. environments where reproducible builds are important. 这对于CI等可重现构建很重要的环境很有用。

See https://github.com/npm/npm/issues/18286 for tracking of the feature. 请参阅https://github.com/npm/npm/issues/18286以跟踪功能。


#6楼

EDIT: the name "lock" is a tricky one, its NPM trying to catch up with Yarn. 编辑:名称“锁”是一个棘手的人,其NPM试图赶上纱线。 It isn't a locked file whatsoever. 它不是一个锁定的文件。 package.json is a user-fixed file, that once "installed" will generate node_modules folder tree and that tree will then be written in package-lock.json . package.json是用户固定的文件,一旦“安装”,它将生成node_modules文件夹树,然后将该树写入package-lock.json So you see, its the other way around - dependency versions will be pulled from package.json as always, and package-lock.json should be called package-tree.json 因此,您可以看到相反的情况-依赖版本将一如既往地从package.json提取,并且package-lock.json应该称为package-tree.json

(hope this made my answer clearer, after so many downvotes) (希望经过这么多次否决之后,我的回答才能更加清晰)


A simplistic answer: package.json have your dependencies as usual, while package-lock.json is "an exact, and more importantly reproducible node_modules tree" (taken from npm docs itself ). 一个简单的答案: package.json像往常一样具有依赖性,而package-lock.json是“精确的,更重要的是可重现的node_modules树”(取自npm docs本身 )。

As for the tricky name, its NPM trying to catch up with Yarn. 至于棘手的名字,它的NPM试图赶上纱。

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

  1. npm中package-lock.json的作用:npm install安装时使用

    简单理解: XYZ 的格式 对应为: 主版本号.次版本号.修订号,版本号递增规则如下: 主版本号:当你做了不兼容的 API 修改, 次版本号:当你做了向下兼容的功能性新增, 修订号:当你做了向下兼容的 ...

  2. npm install 原理分析

    开门见山,npm install 大概会经过上面的几个流程,本篇文章来讲一讲各个流程的实现细节.发展以及为何要这样实现. 嵌套结构 我们都知道,执行 npm install 后,依赖包被安装到了 no ...

  3. npm install下载依赖项时报错 fatal: unable to access ‘https://github.com/nhn/raphael.git/‘: Failed to connect

    解决方案: 1:查看一下自己的node版本,一般高版本下载会出问题,建议使用 12.17.0版本 2:网络延迟的问题,删除package.lock.json和node_modules文件夹,重新ins ...

  4. 2018 年了,你还是只会 npm install 吗

    nodejs 社区乃至 Web 前端工程化领域发展到今天,作为 node 自带的包管理工具的 npm 已经成为每个前端开发者必备的工具.但是现实状况是,我们很多人对这个nodejs基础设施的使用和了解 ...

  5. 2018 年了,你还是只会 npm install 吗?

    转载自:https://www.sohu.com/a/226831801_505818 nodejs 社区乃至 Web 前端工程化领域发展到今天,作为 node 自带的包管理工具的 npm 已经成为每 ...

  6. npm install含义 及vue安装启动项目时报错解决及vue建项目时各文件间的依赖关系...

    全局安装vue-cli,使用命令npm install -g vue-cli. 下载模板代码,使用命令vue init webpack my-project,之后会有一些询问,按需填写即可. 最后会看 ...

  7. npm install是什么意思

    "npm install" 是 Node Package Manager (npm) 的一个命令,用于在项目中安装所需的依赖包.它会读取项目目录中的 "package.j ...

  8. npm常用命令学习(npm install -D,semver版本规范, npm进行版本管理的最佳实践用法)...

    什么是npm npm有两层含义.一层含义是Node的开放式模块登记和管理系统,网址为npmjs.org.另一层含义是Node默认的模块管理器,是一个命令行下的软件,用来安装和管理Node模块. npm ...

  9. npm init 和npm install的区别

    区别 npm init  :生package.json文件,里面有各种依赖包的信息(执行该命令后终端会依次询问 name, version, description 等字段) npm install  ...

最新文章

  1. PyQt5教程——组件 Ⅱ(八)
  2. 下面不属于python第三方库的安装方法的是-关于python中第三方库安装方法和问题解决...
  3. VTK:图表之EdgeWeights
  4. 多个字符合并成一个数组_一个excel多个sheet,需要合并为一个sheet
  5. b站全站排行刷新去掉观看
  6. WorkerMan 入门学习之(三)基础教程-Timer类的使用
  7. JavaScript——exec和match
  8. Arduino 系列传感器应用
  9. 解析g代码c语言程序
  10. [历史]读大卫的《犹太人历史》
  11. html5 canvas 在线图片转换器
  12. 2023五一旅游必备物品清单!快记到手机待办APP里
  13. 计算机审计体会论文,审计论文格式_计算机审计实验报告_审计论文范文3000字
  14. shell编程之特殊符号
  15. Angularjs常见错误原因及解决Error: [$injector:unpr] http://errors.angularjs.org/1.2.9/$injector/unpr?
  16. 12种食物 最有益于男人荷尔蒙
  17. 编写一个程序重复提示用户输入一个国家的首都,一旦收到用户的输入,程序报告用户输入的答案是否正确,假设将50个国家的首都存放在一个字典中,程序提示用户回答所有国家的首都并且显示回答正确的总个数。
  18. 英语----我们快乐生活的一部分
  19. Graphhopper Routing导航API请求参数和返回结果说明
  20. 使用spark建立逻辑回归(Logistic)模型帮Helen找男朋友

热门文章

  1. android 屏幕录像
  2. 算法--------数组--------容纳最多的水
  3. 【剑指offer-Java版】46求 1 + 2 + 3 + ... + n
  4. 如何理解Android中的xmlns
  5. 大年30还多少天_2020余额不足30天!年初许下的愿望你实现了多少?
  6. Java基础之IO笔记
  7. sqlserver怎么查看索引_Sql Server之旅——第六站 为什么都说状态少的字段不能建索引...
  8. AcWing P164 可达性统计 题解
  9. Scala-高阶函数
  10. FreeRTOS学习笔记4-FreeRTOS配置管理