ChatGPT解决这个技术问题 Extra ChatGPT

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

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

这个文件应该保存在源代码管理中吗?

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

简短的回答:是的。一条评论:当 package-lock.json 更改时,您可以只提交该更改,与其他源更改分开。这使得 git log 更容易处理。
如果文件不存在,则无法帮助生成确定性安装。
取决于项目。 github.com/npm/npm/issues/20603
如果您确实信任 npm,其目的是更明确地报告项目正在使用什么。如果您真的想要可预测性,请忽略此文件,而是安装您的 node_modules(请参阅答案+评论中的 .npmrc 和相关配置)并使用它来跟踪实际发生的变化,而不是您的包管理器说明它正在做什么。最终:哪个更重要?您的包管理器或您正在使用的代码。
鉴于纱线的流行及其警告: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.json,我认为这里应该有一些答案来澄清人们何时应该提交 package-lock.json

m
mojoaxel

是的,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 共享格式,本质上是相同的文件,但允许发布。除非部署 CLI 工具或以其他方式使用发布过程来生成生产包,否则不建议这样做。如果 package-lock.json 和 npm-shrinkwrap.json 都存在于包的根目录中,则 package-lock.json 将被完全忽略。


在什么样的项目中提交文件实际上有帮助? semver 和 package.json 的全部意义在于不需要注意更新的兼容依赖项。
关键词是“不应该是”——但在实践中人们并不完全遵循 semver。这就是为什么您可以一起使用 package-lock.json 和 package.json 来轻松更新包,但仍要确保每个开发人员和每个部署的应用程序都使用相同的依赖关系树。
@trusktr:Sindre Sorhus recommends using“用于应用程序的锁定文件,但不适用于包。”
另一件事是,在 NPM 上发布时会忽略 package-lock.json,因此如果开发人员将其用于库开发,那么他们将最大限度地减少从更新的依赖版本中捕获回归的机会,因此将通过最终用户的错误。出于这个原因,不为库开发使用锁定文件会增加发布更少错误的机会。
就我个人而言,我现在不得不求助于将 package-lock.json 添加到我的 .gitignore...这给我带来的问题远远多于解决问题。当我们合并或变基时,它总是会发生冲突,当合并导致 CI 服务器上的 package-lock.json 损坏时,必须继续修复它只是一种痛苦。
k
k0pernikus

是的你应该:

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

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

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

如果 package-lock.json 和 package.json 不同步

如果 package-lock.json 丢失。

因此,在本地运行 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

quote npm doc

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

关于 difference between npm ci vs npm install

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

注意:我发布了一个类似的答案 here


这个答案值得更多信任,尤其是使用 npm ci。使用它可以缓解人们在包锁定方面遇到的大多数问题。
我发现在 package.json 中使用固定版本(没有插入符号或波浪号)是一个更简洁的选择。这使我免于 whose build would fail one day because a random dependency got a breaking update 类问题。虽然它留下了孩子依赖的可能性,导致同样的问题。
我们应该始终使用 npm ci 是否仍然相关?从文档看来这是不正确的。 npm install "这个命令安装一个包和它依赖的任何包。如果包有一个包锁,或者一个 npm 收缩包装文件,或者一个纱线锁文件,依赖的安装将由它驱动,尊重以下内容优先顺序:" npm ci "如果 node_modules 已经存在,它将在 npm ci 开始安装之前自动删除。"当然 npm ci 应该用作 CI/CD 过程的一部分,但在开发机器上似乎过度?
太感谢了!我知道必须有一个只读样式的“npm i”。如果根据文档,锁定文件用于将我同步到之前的更改,但是“npm i”总是会写入 package-lock.json,然后呢?我(正在同步的那个)现在有更改要签入对我来说没有意义。从现在开始,我将尝试使用“npm ci”,看看问题是否消失。
我遇到了这个。但我只需要根据另一个开发人员推送的更改安装一个包。文档说您不能使用 npm ci 安装单个软件包。如果你使用 npm i somepackage@version 它仍然极大地改变了我的 package-lock.json 文件。现在我不知道该怎么办。
x
xer0x

是的,它打算被签入。我想建议它有自己独特的提交。我们发现它给我们的差异增加了很多噪音。


争论是否应该将它检入你的源代码存储库是公平的,但是将这个文件发布到 npm 并没有真正的争论 - 你必须将你的 package-lock.json 或你的 shrinkwrap 文件包含到你的 npm 注册表中。如果您不这样做,您发布的包将受到第一代依赖项的依赖项未固定更改的影响。在第二代以上的依赖项之一发布重大更改之前,您不会注意到这是一个问题,并且您发布的包被神秘地破坏了。这个 package-lock.json 文件是为了解决这个问题而创建的。
@BetoAveiga 的噪音我的意思是,带有 package-lock.json 的提交可以有这么多行的节点包版本,以至于该提交中的任何其他工作都被隐藏了。
我通常将软件包安装与其他工作分开。我从不需要区分像“Installed chai and mocha”这样的提交,因为我已经知道发生了什么变化。
在具有主干和分支的 SCM 系统上工作时,关于 package-lock.json 文件有什么建议吗?我正在对需要合并到主干的分支进行一些更改...我现在是否必须(以某种方式)解决两个 package-lock.json 文件之间的冲突?这感觉很痛苦。
@guerillapresident 据我了解,您是部分正确的。将此文件发布到 npm 没有争议。你不能发布它。
V
Vladimir F Героям слава

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

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

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


+1 提及 npm ci。人们经常提到 package-lock.json 允许确定性安装软件包,但几乎从未提及促进这种行为的命令!许多人可能错误地认为 npm install 安装的正是锁定文件中的内容...
npm ci 不在 npm 5 中。
谢谢!只有在使用 npm ci 时提交 package-lock.json 才有意义。您的团队/首席开发人员可以决定何时更新。如果每个人都只是随意提交它,那就没有意义了,它只会在你的回购中制造噪音。 NPM documentation 应该更清楚地说明这一点。我认为大多数开发人员只是对这个功能感到困惑。
@adampasz 实际上每个开发人员都可以提交锁定文件,并且一旦通过测试并合并,如果包以某种方式被更改,第二个分支只会更新锁定文件(我们不经常更改 package.json,我们很少面临这个问题(
@ahaurat 您的评论是否仍然与我们应该始终使用 npm ci 相关?从文档看来这是不正确的。 npm install "这个命令安装一个包和它依赖的任何包。如果包有一个包锁,或者一个 npm 收缩包装文件,或者一个纱线锁文件,依赖的安装将由它驱动,尊重以下内容优先顺序:" npm ci "如果 node_modules 已经存在,它将在 npm ci 开始安装之前自动删除。"当然,npm ci 应该用作 CI/CD 流程的一部分。
R
ROMANIA_engineer

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

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

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


我希望可以从 npm 文档中对此进行更多说明 - 概述由于不提交 package-lock.json 而导致的具体损失会很有用。一些 repos 可能不需要拥有它所带来的好处,并且可能更喜欢在源代码中没有自动生成的内容。
我可以看到它如何有助于调试(例如两个锁之间的差异)以帮助解决问题。我想它也可以用来防止这类事情,但在共享存储库中使用它也可能会很痛苦,因为它可能会遇到合并冲突。对于初学者来说,我想让事情变得简单,我只会单独使用 package.json,直到我发现确实需要 package-lock.json。
您可能不会在 package.json 中使用 ^,但您可以确定您的依赖项不使用它吗?
每次我更新一个库时,都会重新生成整个锁定文件,使用新的依赖项,并导致令人讨厌的情况。想象一下如果没有签入我的 CI 构建会发生什么,有所有限制......答案是混乱 - 不可靠的构建。有时我被迫覆盖特定的包版本,以免我的整个应用程序崩溃。请不要使用 ^* (example) 创建包,因为它会给最终消费者带来很多问题。
R
Raza

对于在执行 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 行!)。


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

是的,您可以提交此文件。从 npm's official docs

package-lock.json 会为 npm 修改 node_modules 树或 package.json 的任何操作自动生成。它描述了生成的确切树,以便后续安装能够生成相同的树,而不管中间依赖项更新如何。该文件旨在提交到源存储库[.]


安装不会总是更新 node_modules,因此更新 package-lock.json?
不,您可以运行 npm ci 从 package-lock.json 安装
你需要在你的回答中强调,如果你在 repo 上有 package-lock.json,你必须在你的持续集成构建中使用 npm ci
k
k0pernikus

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

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

优点:

如果您遵循严格的版本控制并且不允许自动更新到主要版本以使您免受第三方包中向后不兼容的更改的影响,那么提交 package-lock 会有很大帮助。

如果你更新一个特定的包,它会在 package-lock.json 中更新,并且每个使用存储库的人都会在他们提取你的更改时更新到该特定版本。

缺点:

它可以让你的拉取请求看起来很丑:)

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


如果您使用 npm ci 而不是 npm install,那么缺点就会消失。
范围有点小,但这里是 more info on that excellent advice from @k0pernikus
“项目中的每个人都将使用相同的包版本,您所要做的就是 npm install” 不正确,您需要使用“npm ci”代替
谢谢,@reggaeguitar。为此更新我的答案。
B
Balogun Ridwan Ridbay

全局禁用 package-lock.json

在终端中输入以下内容:

npm config set package-lock false

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


这将创建具有内容 package-lock=false~/.npmrc(至少在我的 macos 上),并且可以在 node_modules/ 旁边的任何特定项目中完成相同的操作(例如 echo 'package-lock=false' >> .npmrc
这对我来说有点有趣,这将是一个负面的。 npm 社区不能接受 package-lock.json 自动生成是糟糕的社区参与。你不应该做会影响团队流程的事情。它应该是启用的选项,而不是强制的。有多少人只是执行“git add *”,甚至没有注意到它并搞砸了构建。如果您有任何类型的基于合并的流程,我知道 git flow 对使用它的人来说就像圣经,这是行不通的。你不能在合并时生成! npm 版本控制已损坏, package : 1.0.0 应该是确定性的!
为什么这被否决了?这显然是禁用不起作用的功能的合法方式。尽管它本身并没有回答这个问题,但它提出了这个问题。即它不再需要回答。我竖起大拇指:)
它被否决的原因是因为您只是禁用了一项功能。
这个答案应该被否决,因为它没有(试图)回答这个问题。
u
user9342572809

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

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

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

但是,如果您使用 lerna 管理具有多个包的项目,则应仅将 package.json 放在存储库的根目录中,而不是在使用 npm 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

M
MagicLAMP

我对 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 的版本控制是在每台服务器上手动完成的,但我注意它们是相同的。

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

您甚至不能用 repo 上的内容覆盖本地生成的 package-lock.json(重置硬源主控),因为如果 package-lock.json 不反映其中的内容,那么当您发出命令时 npm 会抱怨node_modules 由于 npm install,从而破坏了部署。现在,如果这表明 node_modules 中安装了稍微不同的版本,那么这又一次没有给我带来问题。

如果 node_modules 不在你的 repo 上(它不应该在),那么 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,我相信删除的 node_modules,并在 package-lock.json 中安装所有内容而不更新它。这允许我的前端人员升级 javascript 内容,而无需手动干预部署。
M
MedElmaachi

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

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