为什么“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.json
find一个依赖关系的更新版本就可以package-lock.json
。 如果你想有效地固定你的依赖关系,你现在必须指定没有前缀的版本,这意味着你需要把它们写成1.2.0
而不是~1.2.0
或^1.2.0
。 然后, package.json
和package-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.1
但widget
已经更新到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.json
在package-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跳过先前安装的软件包的重复元数据分辨率来优化安装过程。
将来,您将能够使用--from-lock-file
(或类似的)标志只从package-lock.json
进行安装,而不进行修改。
这对于可重复构build非常重要的CI等环境很有用。
一个简单的答案: package.json
像往常一样拥有你的依赖关系,而package-lock.json
是“一个确切的,更重要的可复制的node_modules树”(取自npm docs本身 )。
至于那个棘手的名字,它的NPM试图赶上纱。