是否提交由npm 5创建的package-lock.json文件?


1390

npm 5今天发布,其中一项新功能包括确定性安装以及package-lock.json文件的创建。

该文件应该保留在源代码管理中吗?

我假设它类似于yarn.lockcomposer.lock,这两个都应该保留在源代码管理中。


20
简短的回答:是的。一条评论:当package-lock.json更改时,您可以只提交该更改,而不必进行其他源更改。这使得git log处理起来更容易。
Purplejacket

14
如果文件不存在,将无法帮助您进行确定性安装。
艾伦·


3
如果您真的相信npm肯定,目的是更明确地报告项目正在使用什么。如果您真的希望可预测性,请忽略此文件,而是安装您的node_modules(请参阅Answers + comment中的.npmrc和相关配置),并使用它来跟踪实际更改的内容,而不是软件包管理器指出的内容。归根结底,至尊更重要吗?您的包裹管理员或您使用的代码。
jimmont '18

Answers:


1611

是的,package-lock.json旨在被检查到源代码管理中。如果您使用的是npm 5,则可能会在命令行上看到:created a lockfile as package-lock.json. You should commit this file.根据npm help package-lock.json

package-lock.json会为npm修改node_modules树或的任何操作自动生成package.json。它描述了生成的确切树,因此无论中间依赖项更新如何,后续安装都可以生成相同的树。

该文件旨在提交到源存储库中,并具有多种用途:

  • 描述一个依赖关系树的单一表示,这样可以确保队友,部署和持续集成安装完全相同的依赖关系。

  • 为用户提供“时间旅行”到以前状态的便利 node_modules而不必提交目录本身。

  • 为了通过可读的源代码控制差异更好地了解树的变化。

  • 并允许npm跳过先前安装的软件包的重复元数据解析,从而优化安装过程。

关于一个关键细节 package-lock.json它的是它无法发布,并且如果在顶级软件包以外的任何地方找到它,它将被忽略。它与npm-shrinkwrap.json(5)共享一种格式,该格式本质上是相同的文件,但是可以发布。除非部署CLI工具或使用发布过程来生产生产软件包,否则不建议这样做。

如果软件包的根目录中同时存在package-lock.jsonnpm-shrinkwrap.jsonpackage-lock.json将被完全忽略。


77
在哪种项目中提交文件实际上有帮助?semver和package.json的全部要点是不需要记录更新的兼容依赖项。
curiousdannii

45
关键字是“不必是”-但是在实践中,人们并不能完美地遵循semver。因此,可以一起使用package-lock.json和package.json来轻松更新软件包,但仍要确保每个开发人员和每个部署的应用程序都使用相同的依赖树。
Panu Horsmalahti,2017年

34
@trusktr:Sindre Sorhus 建议对应用程序使用锁定文件,但对程序包不使用。
vine77

23
另一件事是,package-lock.json在NPM上发布时将被忽略,因此,如果开发人员将其用于库开发人员,则他们将从更新的依赖项版本中捕获回归的机会降到最低,因此可以通过最终用户的错误。因此,不为库开发人员使用锁定文件会增加减少发布错误的机会。
trusktr '17

128
就我个人而言,我现在不得不求助于……这package-lock.json给我.gitignore带来的问题比解决问题要多得多。当我们合并或重新设置基准时,它总是会发生冲突,并且当合并导致package-lock.jsonCI服务器上的损坏时,不得不继续对其进行修复是很痛苦的。
Stefan Z Camilleri

111

是的,应该将其签入。我想建议它获得自己的唯一提交。我们发现它为我们的差异增加了很多噪音。


19
公平地辩论是否应将其检查到源代码存储库中,但是将该文件发布到npm并不是真正值得争论的问题-您必须将package-lock.json或收缩包装文件包含到npm注册表中。如果您不这样做,则您发布的软件包将受到第一代依赖项的依赖项未固定更改的影响。您将不会注意到这是一个问题,直到那些第二代或第二代以上的依赖项之一发布了重大更改,并且您发布的程序包被神秘地破坏了。创建该package-lock.json文件就是为了解决该问题。
guerillapresident

8
@BetoAveiga有点杂音,我的意思是说,带有package-lock.json的提交可以包含很多行的节点包版本,因此该提交中的任何其他工作都被隐藏了。
xer0x

7
我通常将软件包安装与其他工作分开。我不需要像“ Installed chai and mocha”这样的提交,因为我已经知道发生了什么变化。
基思

3
package-lock.json在带有中继和分支的SCM系统上工作时,有关文件的任何建议吗?我正在分支中进行一些更改,这些更改需要合并到主干...我现在是否必须(以某种方式)解决两个package-lock.json文件之间的冲突?感觉很痛苦。
kmiklas

3
@guerillapresident据我了解,您部分正确。将此文件发布到npm尚无争议。您无法发布。
蒂姆·高铁

66

是的你应该:

  1. 提交package-lock.json
  2. 使用npm ci而不是npm install在CI和本地开发计算机上构建应用程序时

npm ci工作流程需要的存在package-lock.json


npm install命令的一个很大的缺点是它的意外行为,它可能会使突变package-lock.json,而npm ci仅使用锁定文件中指定的版本并产生错误

  • 如果package-lock.jsonpackage.json不同步
  • 如果package-lock.json缺少a。

因此,在npm install本地运行,尤其是。在拥有多个开发人员的大型团队中,可能会导致内的许多冲突,package-lock.json而开发人员决定完全删除该冲突package-lock.json

然而,有一个强大的用例可以信任项目的依赖项在不同机器之间以可靠的方式重复解决。

从中package-lock.json您可以确切地得到:一个已知的工作状态。

过去,我的项目没有package-lock.json/npm-shrinkwrap.json /yarn.lock文件的由于随机依赖项的更新中断,因此有一天的构建会失败。

这些问题很难解决,因为您有时不得不猜测最新的工作版本是什么。

如果要添加新的依赖项,则仍然可以运行npm install {dependency}。如果要升级,请使用npm update {dependency}npm install ${dependendency}@{version}并提交已更改的package-lock.json

如果升级失败,则可以恢复到上一个​​已知的工作状态package-lock.json


引用文档NPM

强烈建议您将生成的程序包锁定提交给源代码管理:这将允许您团队中的其他任何人,您的部署,您的CI /持续集成以及在包源中运行npm的其他任何人都可以在程序包源中获得完全相同的依赖关系树你在继续发展。此外,这些更改的差异是人类可读的,并且会通知您npm对您的node_modules所做的任何更改,因此您可以注意到是否有任何传递性依赖项被更新,提升等。

并且关于vs 之间npm cinpm install区别

  • 该项目必须具有现有的package-lock.json或npm-shrinkwrap.json。
  • 如果包锁中的依赖项与package.json中的依赖项不匹配, npm ci则将退出并显示错误,而不是更新包锁。
  • npm ci 一次只能安装整个项目:不能使用此命令添加单个依赖项。
  • 如果node_modules已经存在,它将在npm ci开始安装之前自动删除。
  • 它永远不会写入package.json或执行任何程序包锁定:安装实际上是冻结的。

注意:我在这里发布了类似的答案


10
这个答案值得更多功劳,尤其是使用npm ci时。使用此方法可以缓解人们在使用包锁定时遇到的大多数问题。
JamesB

我发现在package.json中使用固定版本(没有插入符号或波浪号)是一种更清洁的选择。这使我免于whose build would fail one day because a random dependency got a breaking update遇到麻烦。虽然这留下了孩子依赖的可能性-导致同样的问题。
Ashwani Agarwal

58

是的,最佳做法是办理登机手续(是,请办理登机手续)

我同意看到差异时会引起很多噪音或冲突。但是好处是:

  1. 保证每个软件包的版本完全相同。在不同时间,不同环境中构建时,此部分最重要。您可以^1.2.3在中使用package.json,但是您如何确保每次npm install都能在开发机和构建服务器中使用相同的版本,尤其是那些间接依赖包?好吧,package-lock.json将确保这一点。(在...的帮助下npm ci它可以基于锁定文件安装软件包)
  2. 它改善了安装过程。
  3. 它有助于新的审核功能npm audit fix(我认为审核功能来自npm版本6)。

3
据我所知,至少在99%的情况下,从不使用semver(npm开发人员无论如何都不理解)应该产生与拥有锁文件相同的行为。我自己的经验是,semver混蛋大多发生在主程序包中(直接依赖项,糟糕的jquery datepickers等)。我对npm的个人经验是,锁定文件永远是噪音。我希望这种智慧在最新版本中不会改变。
斯文德(Svend)

13
+1提及npm ci。人们经常提到a package-lock.json允许确定性安装软件包,但几乎从来没有提及促进这种行为的命令!许多人可能错误地假设npm install安装的文件正是锁定文件中的内容……
ahaurat

npm ci不在npm 5中
。– dpurrington

谢谢!仅在使用时提交package-lock.json才有意义npm ci。您的团队/首席开发人员可以决定何时更新。如果每个人都只是随意提交它,那就没有意义了,它只会在您的仓库中制造噪音。NPM文档应该使这一点更加清楚。我认为大多数开发人员对此功能感到困惑。
adampasz

@adampasz实际上每个开发人员都可以提交锁定文件,并且一旦通过测试并合并,第二个分支就以某种方式更改了软件包(如果我们不更改package(我们不经常更改package.json,则我们较少面对此问题)

38

我不在项目中提交此文件。重点是什么 ?

  1. 它产生了
  2. 这是使用gitlab-ci.yml构建的gitlab中SHA1代码完整性错误的原因

尽管的确,我从未在package.json的lib中使用^,因为我对此有不好的经验。


11
我希望这可以从npm docs中得到更多解释-概述不提交会导致的具体损失package-lock.json。一些回购协议可能并不需要从中获得收益,并且可能更喜欢源中没有自动生成的内容。
PotatoFarmer '18 -10-1

2
我可以看到它对调试(例如两个锁之间的区别)如何有用以帮助解决问题。我猜它也可以用来防止这种情况,但是在共享存储库中使用它可能会很痛苦,因为它可能会遇到合并冲突。对于初学者来说,我想让事情保持简单,我将只使用package.json,直到看到真正需要package-lock.json为止。
radtek

6
您可能不会在package.json中使用^,但是可以确保您的依赖项不使用它?
尼克,

35

对于抱怨git diff时产生噪音的人们:

git diff -- . ':(exclude)*package-lock.json' -- . ':(exclude)*yarn.lock'

我所做的是使用别名:

alias gd="git diff --ignore-all-space --ignore-space-at-eol --ignore-space-change --ignore-blank-lines -- . ':(exclude)*package-lock.json' -- . ':(exclude)*yarn.lock'"

要忽略整个存储库(每个使用它的人)在diffs中的package-lock.json,可以将其添加到.gitattributes

package-lock.json binary
yarn.lock binary

这将导致差异显示“每当更改包锁定文件时二进制文件a / package-lock.json和b / package-lock.json都不同。此外,某些Git服务(尤其是GitLab,但不是GitHub)也将排除在外在网上查看时,这些文件(不再更改10k行!)来自差异文件。


1
gd() { git diff --color-words $1 $2 -- :!/yarn.lock :!/package-lock.json; }在我的.bashrc中,而不是别名中。
apostl3pol

16

是的,您可以提交此文件。来自npm的官方文档

package-lock.json会为npm修改node_modules树或的任何操作自动生成package.json。它描述了生成的确切树,因此无论中间依赖项更新如何,后续安装都可以生成相同的树。

该文件旨在提交到源存储库中。


13
安装不会总是更新node_modules,从而更新package-lock.json吗?
蒂姆·高铁

2
不,您可以运行npm ci从package-lock.json进行安装
William Hampshire

您需要在答案中强调,如果回购中包含package-lock.json,则必须在持续集成构建中使用npm ci
MagicLAMP,

6

全局禁用package-lock.json

在终端中输入以下内容:

npm config set package-lock false

这真的像魔术一样对我有用


2
这会~/.npmrc(至少在我的macOS上)创建内容,package-lock=false并且可以在任何特定项目中同时进行node_modules/(例如echo 'package-lock=false' >> .npmrc
jimmont

6
对我来说,这很消极,这很有趣。npm社区不能接受package-lock.json的自动生成是不好的社区参与。您不应做会影响团队流程的事情。它应该是启用而不是强制的选项。有多少人只是做“ git add *”,甚至没有注意到它并搞砸了构建。如果您有任何一种基于合并的流程,那么我就知道git flow对使用它的人来说就像圣经,这是行不通的。您合并时就无法生成!npm版本控制已损坏,软件包:1.0.0应该具有确定性!
埃里克·特里加

3
为什么这被否决?这显然是禁用无效功能的合法方法。尽管它本身并不能回答问题,但它可以解决这个问题。即它不再需要回答。我竖起大拇指:)
Superole '19

之所以降低投票率,是因为您只是禁用了一项功能。
拉扎

5

是的,提交package-lock.json是一种标准做法

提交package-lock.json的主要原因是项目中的每个人都使用相同的软件包版本。

优点:

  • 如果您遵循严格的版本控制,并且不允许自动更新到主要版本,则可以避免第三方软件包的向后不兼容更改,从而使软件包锁定很有帮助。
  • 如果您更新了某个特定的程序包,则它会在package-lock.json中进行更新,并且使用存储库的每个人都会在获取所做更改后更新到该特定版本。

缺点:-

  • 它会使您的请求请求看起来很丑陋:)'

编辑:-npm install不能确保项目中的每个人都使用相同的软件包版本。npm ci将对此提供帮助。


4
如果您使用npm ci而不是,弊端将消失npm install
k0pernikus

2
范围略有增加,但是这里是@ k0pernikus提供的有关该出色建议更多信息
鲁芬

1
“项目中的每个人都将使用相同的软件包版本,所有您需要做的就是npm install”并非如此,您需要使用“ npm ci”
reggaeguitar

谢谢,@reggaeguitar。为此更新我的答案。
Nikhil Mohadikar

2

我使用npm的目的是生成缩小/缩小的css / js并生成django应用程序服务的页面中所需的javascript。在我的应用程序中,Javascript在页面上运行以创建动画,有时执行ajax调用,在VUE框架内工作和/或与CSS一起工作。如果package-lock.json对package.json中的内容具有某种压倒性的控制权,那么可能需要此文件有一个版本。以我的经验,它要么不会影响npm install所安装的内容,要么会影响到目前为止我所学的应用程序。我不使用mongodb或传统上是瘦客户端的其他此类应用程序。

我从回购中删除package-lock.json,因为npm install会生成此文件,并且npm install是运行该应用程序的每台服务器上部署过程的一部分。node和npm的版本控制是在每台服务器上手动完成的,但是我要注意它们是相同的。

npm install服务器上运行时,它将更改package-lock.json,并且如果服务器上的存储库记录了对文件的更改,则下一次部署WONT允许您从源中提取新更改。那是您无法部署,因为请求将覆盖对package-lock.json所做的更改。

您甚至无法用存储库(重置硬原始主机)上的内容覆盖本地生成的package-lock.json,因为如果package-lock.json无法反映其中的内容,那么在您发出命令时npm都会抱怨由于npm install而导致node_modules中断,因此中断了部署。现在,如果这表明在node_modules中已安装了稍有不同的版本,则再也不会导致我出现问题。

如果node_modules不在您的存储库中(也不应该在存储库中),则应忽略package-lock.json。

如果我丢失了某些内容,请在评论中更正我,但是从该文件中获取版本控制这一点毫无意义。文件package.json中具有版本号,并且我假设此文件是在npm install发生时用于构建软件包的文件,因为当我删除它时,npm install抱怨如下:

jason@localhost:introcart_wagtail$ rm package.json
jason@localhost:introcart_wagtail$ npm install
npm WARN saveError ENOENT: no such file or directory, open '/home/jason/webapps/introcart_devtools/introcart_wagtail/package.json'

并且构建失败,但是当安装node_modules或应用npm来构建js / css时,如果我删除package-lock.json不会发牢骚

jason@localhost:introcart_wagtail$ rm package-lock.json 
jason@localhost:introcart_wagtail$ npm run dev

> introcart@1.0.0 dev /home/jason/webapps/introcart_devtools/introcart_wagtail
> NODE_ENV=development webpack --progress --colors --watch --mode=development

 10% building 0/1 modules 1 active ...

只是添加,我现在将我的package-lock.json提交到我的存储库,并在我的ansible部署中使用npm ci(我相信是delete的node_modules),并将所有内容安装在package-lock.json中而不进行更新。这使我的前端人员可以在无需手动干预部署的情况下升级javascript内容。
MagicLAMP
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.