npm-shrinkwrap.json和package-lock.json有什么区别?


158

随着npm @ 5发布,它现在将写一个,package-lock.json除非npm-shrinkwrap.json已经存在。

我通过以下方式全局安装了npm @ 5:

npm install npm@5 -g

现在,如果npm-shrinkwrap.json在以下期间找到a :

npm install

将显示警告:

npm WARN read-shrinkwrap This version of npm
is compatible with lockfileVersion@1,
but npm-shrinkwrap.json was generated for lockfileVersion@0.
I'll try to do my best with it!

因此,我的收获是我应该用来代替收缩包装package-lock.json

但是为什么要有一种新格式呢?不能package-lock.json做什么npm-shrinkwrap.json

Answers:


176

这些文件的内容完全相同,但是npm处理它们的方式存在一些差异,这在docs网站上以及在npm repo的docs文件中都有介绍,首先明确解决了这两个文件之间的差异

  • package-lock.json永远不会发布到npm,而npm-shrinkwrap默认情况下是
  • package-lock.json 不在顶级程序包中的文件将被忽略,但将遵守属于依赖项的shrinkwrap文件
  • npm-shrinkwrap.json与npm版本2、3和4向后兼容,而package-lock.jsonnpm 5+只能识别

您可以将现有的package-lock.json一个npm-shrinkwrap.json运行npm shrinkwrap

从而:

  • 如果不将软件包发布到npm,则在这两个文件之间进行选择几乎没有影响。您可能希望使用package-lock.json它,因为它是默认名称,对npm初学者来说更清楚。或者,npm-shrinkwrap.json如果您难以确保开发团队中的每个人都在npm 5+上,那么您可能希望使用与npm 2-4的向后兼容性。(请注意,npm 5于2017年5月25日发布;向后兼容将变得越来越不重要,因为大多数人最终都将对此进行升级。)
  • 如果您发布你的包NPM,您有以下两种选择:

    1. 使用package-lock.json准确记录您安装依赖哪个版本,但允许人们在安装包使用兼容的依赖关系的任何版本与版本范围由您决定package.json,或
    2. 使用npm-shrinkwrap.json来确保每个安装您的软件包的人都能获得完全相同版本的所有依赖项


    在文档中(非常简洁地)描述的官方观点是,应该对库使用选项1(大概是为了减少当许多软件包的依赖项都依赖于相同的次级依赖项的稍有不同的版本时引起的软件包重复量) ,但该选项2对于将在全球范围内安装的可执行文件可能是合理的。


2
+1-不过,您能否澄清第二个要点?这种行为与使用npm-shrinkwrap有什么区别?
Rhys

2
@Rhys在实践中,第二个项目符号无关紧要,除非您做的事情很奇怪。基本上,它只是说如果某个库确实以某种方式发布了package-lock.json(这是不可能的),那么如果您将该库安装为其他软件包的依赖项,则package-lock.jsonNPM将忽略该库。但是,如果某个库发布npm-shrinkwrap.json,并且您将该库安装为依赖项,则还将安装库中指定的所有依赖项的确切版本作为辅助依赖项npm-shrinkwrap.json
Mark Amery

您能否添加npm ci现有内容以确保将其安装package-lock.json为只读。(npm install变异package-lock.json引起的混乱和潜在的错误,并且不充分利用其package-lock.json本身。)
k0pernikus

@ k0pernikus我认为npm ci处理方式之间没有任何区别,npm-shrinkwrap.json而且package-lock.json-关于这两个文件之间的区别的问题与它有什么关系?另外,在阅读之后:我认为从npm 5.4开始,npm install...不利用package-lock.json一直是错误的-我相信npm install现在尊重您,package-lock 除非它与您完全不兼容package.json,在这种情况下,后者将优先。(但是我已经离开JavaScript世界了一段时间-我错过了什么吗?)
Mark Amery

27

NPM Developer的解释

这个想法绝对是package-lock.json是收缩包装技术中的最新和最伟大的,而npm-shrinkwrap.json则保留给那些非常关心他们的库具有确切的node_modules的稀有少数人-和适用于希望使用npm @> = 2的CI安装特定树而不必更改npm版本的人。

新的锁文件(“ package-lock.json”)基本上共享所有相同的代码,其格式与npm-shrinkwrap完全相同(您可以相互重命名!)。这也是社区似乎理解的东西:“它有一个锁文件”似乎可以更快地与人一起点击。最后,拥有一个新文件意味着我们可以通过使用rinkerwrap进行低风险的向后兼容,而不必执行父帖子中提到的allow-publication之类的怪异事情。


18
我仍然不清楚区别。如果npm-shrinkwrap是用于精确的node_modules...。我认为package-lock.json锁定小于精确?如果是这样,那不是锁定npm-shrinkwrap就是锁定?
dman

你错了@dman。package-lock是npm-shrinkwrap的新版本。package-lock是选择退出的(因此您必须删除此功能,因为它是默认启用的),npm-shrinkwrap是选择加入的(因此您必须启用它,因为它不包含在我的默认设置中)。他们之所以引入package-lock的原因是:1.用户现在具有一种处理依赖关系的保护程序,因为默认情况下它是启用的; 2.该名称暗含了与“ shrinkwrap”相反的含义。npm-shrinkwrap具有一些特殊的依赖行为设置,而package-lock现在还没有。npm-shrinkwrap现在已过时。
严重M

10
这是不正确的。通过说package-lock是npm-shrinkwrap的新版本,就是说它是替代品。npm-shrinkwrap没有被弃用,并且与package-lock.json有所不同。此外,package-lock.json 有一个错误,而npm -shrinkwrap 没有...因此强调了更多,因此它们不是同一代码。
dman

package-lock.json也是侵入性的。因此,如果您调用“ npm i”,则很容易引起scm冲突,而收缩包装应显式生成,并且不会在ci服务器上引起冲突。是的,我在这里可能是错的。
诺列霍夫

@dman “ package-lock.json有错误,而npm-shrinkwrap没有错误” -不,没有。您所链接的问题中没有任何迹象表明;它甚至没有提到npm-shrinkwrap。正如我在回答中所指出的那样,将a转换package-lock.json为an npm-shrinkwrap.json实际上只是通过重命名文件来完成的。它们 “相同的代码”。
Mark Amery

12

我认为这个想法是默认情况下会进行保存和收缩包装,但要避免在不需要的地方发生收缩包装的任何潜在问题。因此,他们只是给了它一个新的文件名,以避免任何冲突。来自npm的人在这里对此进行了更全面的解释:

https://www.reddit.com/r/javascript/comments/6dgnnq/npm_v500_released_save_by_default_lockfile_better/di3mjuk/

相关报价:

默认情况下,npm在您的源目录中发布大多数文件,并且人们已经发布了多年的包装纸。我们不想破坏兼容性。默认情况下使用--save和rinkrinkwrap,存在很大的风险,使其无意间进入注册表并在注册表中传播,并且基本上使我们能够更新deps和dedupe ... null。

因此,我们选择了一个新名称。然后我们突然选择了一个新名称。新的锁文件基本上共享所有相同的代码,格式完全相同

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.