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

Do I commit the package-lock.json file created by npm 5?

提问人:rink.attendant.6 提问时间:5/27/2017 更新时间:11/9/2023 访问量:1007240

问:

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

此文件是否应该保存在源代码管理中?

我假设它类似于 yarn.lockcomposer.lock,它们都应该保存在源代码控制中。

节点.js git npm 版本控制 锁文件

评论

73赞 Purplejacket 8/30/2017
简短的回答:是的。一条评论:当package-lock.json更改时,您可以仅提交该更改,与其他源更改分开。这使得处理起来更容易。git log
34赞 Alan H. 9/30/2017
如果文件不存在,则无法帮助生成确定性安装。
10赞 Gajus 5/13/2018
取决于项目。github.com/npm/npm/issues/20603
6赞 jimmont 12/1/2018
如果你真的信任 npm,那么这样做的目的是更明确地报告项目正在使用什么。如果你真的想要可预测性,请忽略这个文件,而是安装你的node_modules(参见 answers+comment 中的 .npmrc 和相关配置),并使用它来跟踪实际更改的内容,而不是你的包管理器声明它正在做什么。归根结底:哪个更重要?您的包管理器或您正在使用的代码。
4赞 nealmcb 8/5/2020
鉴于纱线的流行及其警告:,我认为这里应该有一些答案来澄清人们何时不应该承诺package-lock.json found. Your project contains lock files generated by tools other than Yarn. It is advised not to mix package managers in order to avoid resolution inconsistencies caused by unsynchronized lock files. To clear this warning, remove package-lock.jsonpackage-lock.json

答:

2592赞 vine77 5/27/2017 #1

是,旨在签入源代码管理。如果您使用的是 npm 5+,您可能会在命令行上看到以下通知: 根据 npm 帮助package-lock.jsonpackage-lock.jsoncreated a lockfile as package-lock.json. You should commit this file.

package-lock.json针对 npm 的任何操作自动生成 修改树或 .它描述了 生成的确切树,以便后续安装能够 生成相同的树,而不考虑中间依赖项更新。node_modulespackage.json

此文件旨在提交到源存储库中,并提供 各种用途:

  • 描述依赖关系树的单一表示形式,以便保证团队成员、部署和持续集成安装完全相同的依赖关系。

  • 为用户提供一种工具,让他们可以“穿越”到以前的状态,而不必提交目录本身。node_modules

  • 通过可读的源代码管理差异,提高树更改的可见性。

  • 并通过允许 npm 跳过以前安装的包的重复元数据解析来优化安装过程。

一个关键的细节是它不能发布,而且它 如果在顶级包以外的任何地方找到,则将被忽略。它分享 带有npm-shrinkwrap.json的格式,本质上是相同的文件,但 允许发布。除非部署 CLI 工具或 否则,使用发布过程来生成生产包。package-lock.json

如果两者 和 都存在于 的根目录中 一个包,将被完全忽略。package-lock.jsonnpm-shrinkwrap.jsonpackage-lock.json

评论

139赞 curiousdannii 5/27/2017
在什么样的项目中,提交文件实际上很有帮助?semver 和 package.json 的全部意义在于,不需要注意更新的兼容依赖项。
79赞 Panu Horsmalahti 5/31/2017
关键词是“不应该需要”——但在实践中,人们并没有完全遵循 semver。因此,您可以同时使用 package-lock.json 和 package.json,以便轻松更新包,同时确保每个开发人员和每个已部署的应用程序都使用相同的依赖关系树。
45赞 vine77 6/24/2017
@trusktr:Sindre Sorhus 建议使用“锁定应用程序的文件,但不对包使用”。
39赞 trusktr 7/20/2017
另一件事是,在 NPM 上发布时会忽略package-lock.json,因此,如果开发人员将其用于库开发,那么他们将最大程度地减少从更新的依赖项版本中捕获回归的机会,从而将该错误传递给最终用户。因此,不使用锁定文件进行库开发会增加发布更少错误的机会。
196赞 Stefan Z Camilleri 8/14/2017
就我个人而言,我现在不得不求助于增加我的......它给我带来的问题远远多于解决它们的问题。当我们合并或变基时,它总是会发生冲突,当合并导致 CI 服务器上损坏时,必须继续修复它是一种痛苦。package-lock.json.gitignorepackage-lock.json
143赞 xer0x 6/17/2017 #2

是的,它旨在办理登机手续。我想建议它有自己独特的提交。我们发现它为我们的差异增加了很多噪音。

评论

26赞 guerillapresident 9/10/2017
争论是否应该将其签入源代码存储库是公平的,但将此文件发布到 npm 并不是真正的争论 - 您必须将 package-lock.json 或 shrinkwrap 文件包含在 npm 注册表中。否则,已发布的包将受到第一代依赖项的未固定依赖项更改的约束。在其中一个第 2+ 代依赖项发布重大更改之前,您不会注意到这是一个问题,并且您发布的包变得神秘地损坏。创建此package-lock.json文件是为了解决该问题。
12赞 xer0x 11/25/2017
@BetoAveiga噪音,我的意思是带有 package-lock.json 的提交可以有如此多的节点包版本行,以至于该提交中的任何其他工作都会被隐藏。
9赞 ki9 12/15/2017
我通常将软件包安装与其他工作分开。我永远不需要像“已安装的柴和摩卡”这样的提交,因为我已经知道发生了什么变化。
4赞 kmiklas 1/24/2018
在具有中继和分支的 SCM 系统上工作时,对文件有什么建议吗?我正在对需要合并到主干的分支进行一些更改......我现在是否必须(以某种方式)解决两个文件之间的冲突?这感觉很痛苦。package-lock.jsonpackage-lock.json
9赞 Tim Gautier 5/10/2018
@guerillapresident 据我了解,你是部分正确的。将此文件发布到 npm 是没有争议的。您无法发布它。
26赞 Bablu Singh 10/6/2017 #3

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

package-lock.json对于修改树或 .它描述了生成的确切树,以便后续安装能够生成相同的树,而不考虑中间依赖项更新。npmnode_modulespackage.json

此文件旨在提交到源存储库中[.]

评论

14赞 Tim Gautier 5/10/2018
安装不会总是更新node_modules,从而更新package-lock.json吗?
3赞 Kyle Krzeski 8/28/2019
不,您可以从package-lock.json运行安装npm ci
1赞 MagicLAMP 5/4/2020
你需要在回答中强调,如果你在存储库上有package-lock.json,你必须在持续集成构建中使用 npm ci
121赞 Xin 6/15/2018 #4

是的,最佳做法是办理登机手续(YES, CHECK-IN)

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

  1. 保证在开发和生产环境之间每个包的版本完全相同。这部分在不同时间的不同环境中构建时最为重要。您可以在 中使用,但是如何确保每次都会在开发计算机和构建服务器中获取相同的版本,尤其是那些间接依赖包?好吧,将确保这一点。(借助它根据锁定文件安装软件包)^1.2.3package.jsonnpm installpackage-lock.jsonnpm ci
  2. 它改进了安装过程。
  3. 它有助于新的审计功能。npm audit fix

评论

28赞 ahaurat 2/12/2019
+1 提及 .人们经常提到 a 允许确定性地安装软件包,但几乎从未提及促进这种行为的命令!许多人可能错误地认为安装的内容正是锁定文件中的内容......npm cipackage-lock.jsonnpm install
0赞 dpurrington 4/9/2019
npm ci 不在 npm 5 中。
2赞 adampasz 8/17/2019
谢谢!只有在使用 时提交 package-lock.json才有意义。您的团队/首席开发人员可以决定何时更新。如果每个人都只是任意地提交它,那么它就没有意义了,它只是在你的 repo 中制造噪音。NPM 文档应该更清楚地说明这一点。我认为大多数开发人员只是对此功能感到困惑。npm ci
0赞 Xin 8/19/2019
@adampasz实际上每个开发人员都可以提交锁定文件,一旦通过测试并合并,如果以某种方式更改了软件包,第二个分支就会更新锁定文件(我们不经常更改package.json,我们较少遇到这个问题(
1赞 Thomas 4/22/2021
@ahaurat 您的评论是否仍然与我们应该始终使用 npm ci 相关?从文档来看,这似乎是不正确的。npm 安装“此命令将安装一个软件包及其所依赖的任何软件包。如果包有一个 package-lock,或者一个 npm shrinkwrap 文件,或者一个 yarn lock 文件,依赖项的安装将由它驱动,遵循以下优先顺序:“ npm ci ”如果一个node_modules已经存在,它将在 npm ci 开始安装之前自动删除。”当然,npm ci 应该用作 CI/CD 过程的一部分。
52赞 Raza 6/22/2018 #5

对于那些抱怨做 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'"

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

package-lock.json binary
yarn.lock binary

这将导致差异显示“每当更改包锁定文件时,二进制文件 a/package-lock.json 和 b/package-lock.json 都会有所不同。此外,一些 Git 服务(特别是 GitLab,但不是 GitHub)也会在在线查看时从差异中排除这些文件(不再更改 10k 行!

评论

2赞 apostl3pol 5/15/2019
我在我的 .bashrc 中而不是别名。gd() { git diff --color-words $1 $2 -- :!/yarn.lock :!/package-lock.json; }
0赞 Niels Bom 10/18/2022
盲目承诺可能很危险:snyk.io/blog/......
58赞 Deunz 7/12/2018 #6

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

  1. 它被生成
  2. 这是 gitlab 中 SHA1 代码完整性错误的原因,具有gitlab-ci.yml构建

虽然我确实从未在我的 package.json 中使用 ^ 作为库,因为我对它有不好的体验。

[编辑]这个答案已经过时了(2018 年),公平地说,它也缺乏知识。截至 2023 年 4 月,我的答案是 => 当然,您必须提交此文件: 例如,CI 平台上的标准安装命令需要该文件才能正常工作,以确保依赖树与提交的完全相同;npm ci

评论

14赞 PotatoFarmer 10/2/2018
我希望这可以从 npm 文档中得到更多阐述 - 概述您因不提交而具体损失的内容会很有用。某些存储库可能不需要拥有它带来的好处,并且可能更喜欢在源代码中没有自动生成的内容。package-lock.json
2赞 radtek 3/15/2019
我可以看到它如何用于调试(例如两个锁之间的差异)以帮助解决问题。我想它也可以用来防止这些事情,但是在共享回购中使用它也可能是一种痛苦,它可能会因此而遇到合并冲突。首先,我想让事情变得简单,我会单独使用package.json,直到我看到真正需要package-lock.json。
18赞 neiker 5/16/2019
您可能不会在package.json使用^,但您可以确定您的依赖项不使用它?
1赞 HellBaby 12/22/2021
每次我更新库时,整个锁定文件都会重新生成,使用新的依赖项,并导致令人讨厌的情况。想象一下,如果没有签入,我的 CI 构建会发生什么,并且存在所有限制......答案是混沌 - 不可靠的构建。有时,我被迫覆盖特定的软件包版本,以免使整个应用程序崩溃。请不要使用 、 或 (example) 创建包,因为它会给最终消费者带来很多问题。^*
2赞 badr aldeen 4/3/2023
如果项目中忽略了package-lock.json,可能会导致版本冲突、包升级意外或开发环境与生产环境之间存在差异等问题。
10赞 Balogun Ridwan Ridbay 10/27/2018 #7

全局禁用package-lock.json

在终端中键入以下内容:

npm config set package-lock false

这对我来说真的像魔术一样有效

评论

2赞 jimmont 12/1/2018
这会创建(至少在我的 macOS 上)内容,并且可以在任何特定项目中完成相同的操作(例如~/.npmrcpackage-lock=falsenode_modules/echo 'package-lock=false' >> .npmrc
9赞 Eric Twilegar 2/6/2019
对我来说,这将是负面的,这有点好笑。NPM 社区无法接受package-lock.json自动生成是糟糕的社区参与。不应执行可能影响 Teams 流程的操作。它应该是一个启用选项,而不是强制的。有多少人只是做“git add *”,甚至没有注意到它并搞砸了构建。如果您有任何基于合并的流程,我知道 git flow 对使用它的人来说就像圣经一样,这是行不通的。你不能在合并时生成!npm 版本控制坏了,包:1.0.0 应该是确定性的!
3赞 Superole 2/7/2019
为什么这被否决了?这显然是禁用不起作用的功能的合法方法。虽然它本身没有回答这个问题,但它提出了这个问题。也就是说,它不再需要回答。我竖起大拇指:)
2赞 Raza 5/8/2019
它被否决的原因是因为你只是禁用了一项功能。
5赞 Gershom Maes 2/6/2021
这个答案应该被否决,因为它没有(试图)回答这个问题
-1赞 MagicLAMP 1/9/2019 #8

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

我从 repo 中删除了 package-lock.json 因为 npm install 会生成此文件,而 npm install 是运行应用的每台服务器上部署过程的一部分。node 和 npm 的版本控制是在每台服务器上手动完成的,但我小心它们是否相同。

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

你甚至不能用 repo 上的内容覆盖本地生成的package-lock.json(重置硬源主节点),因为 npm 会在你发出命令时抱怨,如果package-lock.json由于 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

> [email protected] dev /home/jason/webapps/introcart_devtools/introcart_wagtail
> NODE_ENV=development webpack --progress --colors --watch --mode=development

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

评论

0赞 MagicLAMP 5/6/2020
补充一点,我现在已将我的package-lock.json提交到我的存储库,并且在我的 ansible 部署中使用 npm ci,我认为这是删除node_modules,并在不更新的情况下将所有内容安装在 package-lock.json 中。这允许我的前端人员升级 javascript 内容,而无需在部署中进行手动干预。
391赞 k0pernikus 5/22/2019 #9

是的,您应该:

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

该工作流要求存在 .npm cipackage-lock.json


命令的一大缺点是它的意外行为,它可能会改变 ,而只使用锁定文件中指定的版本并产生错误npm installpackage-lock.jsonnpm ci

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

因此,在本地运行,尤其是在具有多个开发人员的大型团队中,可能会导致开发人员内部发生大量冲突,从而决定完全删除。npm installpackage-lock.jsonpackage-lock.json

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

从中得到的正是:已知的工作状态。package-lock.json

过去,我有一些没有 / / 文件的项目,这些文件的构建有一天会失败,因为随机依赖项得到了重大更新。package-lock.jsonnpm-shrinkwrap.jsonyarn.lock

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

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

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


引用 npm doc

强烈建议您将生成的包锁提交到 源代码管理:这将允许团队中的其他任何人,你的 部署、CI/持续集成以及运行的任何其他人 npm install 来获取完全相同的依赖项 您正在开发的树。此外,与这些的差异 更改是人类可读的,并且会通知您 npm 的任何更改 制作到您的node_modules,因此您可以注意到是否有任何传递 依赖项已更新、提升等。

关于 npm cinpm install 之间的区别

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

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

评论

57赞 JamesB 6/14/2019
这个答案值得更多赞誉,尤其是使用 npm ci。使用此功能可以缓解人们在包锁定方面遇到的大多数问题。
4赞 Ashwani Agarwal 5/29/2020
我发现在package.json中使用固定版本(没有插入符号或波浪号)是一个更干净的选择。这使我免于某种问题。尽管它留下了孩子的依赖性的可能性,但同样的问题。whose build would fail one day because a random dependency got a breaking update
2赞 Thomas 4/22/2021
我们应该始终使用 npm ci 是否仍然相关?从文档来看,这似乎是不正确的。npm 安装“此命令将安装一个软件包及其所依赖的任何软件包。如果包有一个 package-lock,或者一个 npm shrinkwrap 文件,或者一个 yarn lock 文件,依赖项的安装将由它驱动,遵循以下优先顺序:“ npm ci ”如果一个node_modules已经存在,它将在 npm ci 开始安装之前自动删除。”当然,npm ci 应该用作 CI/CD 过程的一部分,但在开发机器上似乎过多了??
2赞 diox8tony 7/13/2021
非常感谢!我知道必须有一个只读样式的“npm i”。如果根据文档,锁定文件用于将我同步到之前的任何更改,但是“npm i”总是会写入package-lock.json然后呢?对我来说(正在同步的那个)现在有更改要签入是没有意义的。从现在开始,我将尝试使用“npm ci”,看看问题是否消失。
2赞 Samo 9/19/2022
这应该是公认的答案。每次不同的开发人员运行它时,使用都会导致更改。完全抵消了拥有它的好处。npm ipackage-lock.json
16赞 Nikhil Mohadikar 5/28/2019 #10

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

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

优点:

  • 如果您遵循严格的版本控制,并且不允许自动更新到主要版本,以避免第三方软件包中向后不兼容的更改,那么提交软件包锁定有很大帮助。
  • 如果您更新了某个特定包,则该包将在 package-lock.json 中更新,并且使用存储库的每个人在接受您的更改时都会更新到该特定版本。

缺点:

  • 它会让你的拉取请求看起来很丑陋:)

npm install不会确保项目中的每个人都使用相同的包版本。 将对此有所帮助。npm ci

评论

8赞 k0pernikus 9/6/2019
如果您使用 而不是 .npm cinpm install
2赞 ruffin 12/9/2019
范围有点小,但这里有更多关于@k0pernikus优秀建议的信息
2赞 reggaeguitar 3/13/2020
“项目中的每个人都将使用相同的包版本,您所要做的就是 npm install” 不对,您需要使用“npm ci”代替
0赞 Nikhil Mohadikar 3/17/2020
谢谢,@reggaeguitar。更新我的答案。
0赞 Matthias 4/20/2023
@reggaeguitar你有消息来源吗?这正是锁定文件---保证确切安装版本的作用。
5赞 user2226755 7/7/2020 #11

所有答案都说“是”,但这也取决于项目,文档说:

关于package-lock.json的一个关键细节是它不能发布,如果在顶级包以外的任何地方找到它,它将被忽略。

这意味着你不需要在 npm 上发布依赖项,但你需要在你的存储库中使用来锁定你的测试依赖项的版本,构建依赖项......package-lock.jsonpackage-lock.json

但是,如果您使用 lerna 来管理具有多个包的项目,则应将 only 放在 repo 的根目录上,而不是在每个子包中使用 .你会得到这样的东西:package.jsonnpm init

.git
lerna.json
package.json
package-lock.json        <--- here
packages/a/package.json
packages/a/lib/index.js
packages/b/package.json
packages/b/lib/index.js
1赞 MedElmaachi 2/24/2021 #12

将package-lock.json提交到源代码版本控制意味着项目将使用特定版本的依赖项,该依赖项可能与package.json中定义的依赖项匹配,也可能不匹配。如您所见,虽然依赖项具有没有任何插入符号 (^) 和波浪号 (~) 的特定版本,但这意味着依赖项不会更新到最新版本。npm install 将选择相同的版本,以及我们当前版本的 Angular 所需的版本。

注意:如果我将任何插入符号 (^) 和波浪号 (~) 添加到要在 CI 期间更新的依赖项中,package-lock.json强烈建议提交它。

评论

1赞 Matthias 9/7/2022
除了查看依赖项的 semver 范围是否具有范围(或)而不是确切版本之外,还要考虑依赖项的依赖项(等)是否具有范围。他们可能会这样做。Npm 着眼于它们,而不仅仅是顶层。因此,在 package.json 中使用确切版本并不能实现锁定文件的稳定性。^~
17赞 Matthias 4/20/2023 #13

是的

答案是肯定的,绝对总是把你的锁文件提交到 git。

类似于 git 哈希

如果你使用 git,你应该使用 lockfile,因为它们具有相同的目的:

  • git 哈希保证 git 存储库中文件内容的稳定性。
  • 锁定文件保证了node_modules内容的稳定性。

因为。。。

  • Git 存储库中的文件可能会随时间而变化,但 Git 哈希是指文件的确切快照。
  • npm 注册表中的 npm 包可能会随时间而更改,但 lockfile 指的是依赖项的确切快照。

来自包管理器本身

包管理器供应商明确表示您应该提交锁定文件

npm

强烈建议您将生成的包锁提交到源代码管理...

https://docs.npmjs.com/cli/v6/configuring-npm/package-locks

在没有锁定文件的情况下安装时,它会清楚地告诉您提交锁定文件:npm

npm notice  created a lockfile as package-lock.json. You should commit this file.

锁定文件应提交到所有项目

https://classic.yarnpkg.com/blog/2016/11/24/lockfiles-for-all/

PNPM的

您应该始终提交锁定文件 ()。pnpm-lock.yaml

https://pnpm.io/git

原因

一致性

单个提交应始终相同,并且其生成输出不应随时间而更改。

来自 npm:

[a lockfile] 将允许团队中的其他任何人、部署、CI/持续集成以及在包源中运行 npm install 的任何人获得与你正在开发的完全相同的依赖树。

从纱线:

如果您不存储最终安装的版本,则有人可能会安装同一组依赖项,并最终根据安装时间获得不同的版本。这可能会导致“在我的机器上工作”问题,应避免。

变更的可追溯性

当某些事情发生变化时,你希望 git 跟踪该变化。

来自 npm:

[使用锁定文件] [安装] 更改的差异是人类可读的,并且会通知您 npm 对 所做的任何更改,因此您可以注意到是否有任何传递依赖项被更新、提升等。node_modules

稳定性和安全性

避免引入错误和漏洞。

从纱线:

由于软件包作者是人,他们可能会犯错误,因此他们可能会在次要版本或补丁版本中发布意外的重大更改。如果您在不打算安装此中断性变更时安装,可能会产生不良后果,例如在生产环境中破坏您的应用。

如果包作者是恶意的,或者受到恶意攻击,并且发布了错误的版本,则不希望该代码在您不知情的情况下最终运行。

常见异议

“没有意义”

这是一个“无知的论点”,这是一个逻辑谬误。换句话说,“我不知道原因,所以没有”。

“它已生成”

如果这个文件是自动生成的,我们为什么要提交它?为什么npm不能根据我的package.json再次生成它。

来自评论

回应:被生成不是缺陷。生成 Git 提交哈希;我们不应该使用 git 吗?事实是,锁文件不是从package.json确定生成的,因为它容易受到时间和 npm 注册表中包状态的影响。这是一个快照,用于稳定性。

“这会导致合并冲突”

解决签入锁定文件中的合并冲突是一种负担。

来自 npm:

自 开始,可以通过手动修复任何冲突,然后再次运行来解决这些冲突。[email protected]package.jsonnpm install [--package-lock-only]

从纱线:

当 lockfile 中出现合并冲突时,Yarn 会在运行时自动为您处理冲突解决。yarn install

https://engineering.fb.com/2017/09/07/web/announcing-yarn-1-0/

来自 pnpm:

pnpm 可以自动解决 中的合并冲突。如果有冲突,只需运行并提交更改即可。pnpm-lock.yamlpnpm install

因此,所有包管理器都会自动解决锁定文件合并冲突。在旧版本中可能不是这种情况,但现在是这样。

唯一失败的情况是 本身有冲突,因为您无法从无效的 .您必须手动解决这些冲突,因为无论如何都必须这样做package.jsonpackage.json

“合并冲突干扰了 PR 和 MR”

使用锁定文件会大大增加合并一个 PR 导致第二个 PR 与基分支发生冲突的可能性。

https://docs.renovatebot.com/noise-reduction/#lock-file-considerations

这是真的。Git 提供程序(GitHub、GitLab 等)不会自动解决锁文件冲突,因此这可能会增加合并的负担。但是,在权衡此缺点时,请了解锁定文件通常不会更改;它们仅在 deps 更改时更改,或者当开发人员专门更改文件或已安装的 deps 时才会更改。package.jsonnode_modules

“它发出差异噪音”

如果 diff 工具显示 lockfile diffs,则会产生很多噪音。

这是事实,但这是一个工具问题,许多工具都可以正常处理(例如自动最小化、分页或虚拟滚动)。如果您根本不想看到锁定文件的差异,请尝试 ,或者将文件标记为二进制(但是,如果这对您很重要,您不会看到它的差异)。git diff -- . ':(exclude)yarn.lock'.gitattributes

“精确版本已经足够好了”

为什么不通过删除插入符号和波浪号(^ 和 ~)来硬编码依赖项版本呢?

评论

这个想法是,在依赖 semver 表达式中不使用范围与拥有锁定文件完成相同的工作。package.json

这是错误的。即使指定了确切的版本,依赖项也有自己的依赖项,这些依赖项可能使用其版本的范围,而不是确切版本。因此,这最终不会锁定整个依赖树,而只会锁定它的顶部。

“应用程序的锁定文件,库没有锁定文件”

这种反对意见的例子:

人们认为,库需要对最前沿的 deps 做出反应,而没有锁定文件支持这一点。

从纱线:

有些人想知道为什么图书馆应该使用锁定文件......在开发库时使用 lockfiles 会产生一种虚假的安全感,因为您的用户可能安装的版本与您不同。

这在逻辑上似乎是有道理的,但让我们更深入地研究这个问题。

纱线文章深入探讨了这一反对意见。请阅读它。

此参数中的一个常见错误是认为,如果不提交锁定文件,它就不存在。实际上,它仍然存在于您的计算机上,锁定了您的依赖项。gitignoring 锁文件并不能改善这种情况。

如果库维护者希望持续测试兼容性,那么他们应该在安装和构建库之前删除他们的锁文件(无论锁文件是否签入!与签入锁定文件的唯一区别是,当这种情况发生时,您有node_modules状态的持久记录,因此将来可以重现它。

为此,有像 greenkeeperrenovate-bot 这样的机器人。Greenkeeper 提倡签入锁定文件(Greenkeeper 和 Lockfiles:天作之合),renovate-bot 不发表任何意见,但如果存在,会提交锁定文件

“不同系统以不同的方式生成锁定文件”

这是一个提到的声明(例如这里):不同的操作系统生成不同的锁文件内容。如果是这种情况,这是一个错误。

但是,不同版本(或任何包管理器)可能会产生不同的锁定文件输出。我还没有证实这一点,但假设如果是这样,那么为稳定付出的代价很小。要解决此问题,贡献者需要使用 nvm 等工具切换其包管理器版本。npm

“锁定文件可能存在安全风险”

参见 Snyk - 为什么 npm lockfiles 会成为注入恶意模块的安全盲点

这是一个真正的风险。带有 lockfile 的公共项目可能会收到带有 lockfile 内容的恶意 PR,一旦拉取和安装分支,这些内容可能会危及维护者的机器。

使用 CI 检查(如 lockfile-lint 或 simply 或 (在 Yarn 1 上))来防御这种情况,并可能在您的 .npm ciyarn --immutableyarn --frozen-lockfileignore-scriptsnpmrc

每当您安装包含不受信任代码的包时,都会存在此风险。

综上所述

始终提交锁定文件。

1赞 vijay 8/25/2023 #14

TLTR系列

在以下情况下提交。


  1. 如果提交,则将新包添加到项目中。npm/yarn
  2. 如果,则提交,任何更改正在更新文件。package.json.lock
  3. 如果 packages、nodejs、yarn 中的任何版本更改正在更新文件,请提交。.lock

不要在以下情况下做出承诺。


  1. 您没有编码并获取更新的锁定文件it means other dev did not push lock file during above specified commit points

  2. 您刚刚提取并获取更新的锁定文件it means other dev did not push lock file during above specified commit points

  3. 刚刚做了 git clone 并获取更新的锁定文件it means other dev did not push lock file during above specified commit points

  4. 您编写了一个功能,但没有执行与上述指定提交点相关的任何操作,但锁定文件仍在更新it means other dev did not push lock file during above specified commit points

结论

锁定文件的主要目标是安装哪个项目应该具有 ULTRA ACCURATED 库和版本all developersall environmentsall machines

所以基本上,只有 3 种情况可以提交。

评论

1赞 Matthias 10/4/2023
这个问题是关于将文件添加到 Git,而不是提交对它的更改
1赞 Ini 11/9/2023 #15

是的,你应该提交它,因为它包含有关已安装内容的信息,并且这些信息可能很有用——例如,您可以通过在 CI/CD 管道中执行来实现确定性构建,或者当其他开发人员想要完全安装您安装的相同依赖项时,您可以通过 .npm cinpm ci