ChatGPT解决这个技术问题 Extra ChatGPT

我应该提交 yarn.lock 文件吗?它的用途是什么?

在您执行 yarn install 后,Yarn 会创建一个 yarn.lock 文件。

这应该提交到存储库还是忽略?它是干什么用的?

恕我直言,这个问题(以及以下大多数答案)是不完整的,因为缺少“我们应该如何以及何时重新生成 yarn.lock 文件?”的问题。
您现在知道如何以及何时了吗?
@MarkHu 在这里找到它:yarnpkg.com/lang/en/docs/yarn-lock/#toc-managed-by-yarn 所以基本上:Your yarn.lock file is auto-generated and should be handled entirely by Yarn. As you add/upgrade/remove dependencies with the Yarn CLI, it will automatically update your yarn.lock file.

a
aless80

是的,您应该签到,请参阅Migrating from npm

它有什么用?
npm 客户端不确定地将依赖项安装到 node_modules 目录中。这意味着根据安装依赖项的顺序,node_modules 目录的结构可能因人而异。这些差异可能会导致在我的机器上工作 需要很长时间才能找到的错误。

Yarn 通过使用锁定文件和确定性和可靠的安装算法解决了有关版本控制和非确定性的这些问题。这些锁定文件将已安装的依赖项锁定到特定版本,并确保每次安装在所有机器上的 node_modules 中产生完全相同的文件结构。


很好的发现。我从他们的 docs 中找到以下答案“它是干什么用的?”:“npm 客户端不确定地将依赖项安装到 node_modules 目录中。这意味着根据安装依赖项的顺序,结构node_modules 目录可能因人而异。这些差异可能导致“在我的机器上工作”的错误,需要很长时间才能找到。
继续:“Yarn 通过使用锁定文件和确定性和可靠的安装算法解决了这些版本控制和非确定性问题。这些锁定文件将已安装的依赖项锁定到特定版本,并确保每次安装都会产生完全相同的文件结构所有机器上的 node_modules。”
而不是说“找不到锁定文件”。它应该只是说“生成 yarn.lock 文件”。 Duh :) 这不是一个错误,但前者听起来像是一个错误。在相反的情况下,后者对于任何人来说都足够令人震惊(他们希望有一个 yarn.lock 文件,但显然没有)。
我很欣赏 yarn.lock 将我们的项目锁定到特定的包版本,但我确实觉得“锁”这个词的使用是不幸的。通常 lock files(例如 .ldb)是一种将资源一次限制为一个进程的方法,以防止中间更新可能导致的损坏。这样的锁文件绝对不应该提交给版本控制,这可能是大多数关于 yarn.lock 的困惑的根源。
我真的不喜欢“你不需要阅读或理解这个文件”这句话。这是维护项目的重要文件。
V
VoxPelli

取决于你的项目是什么:

您的项目是应用程序吗?然后:是的,您的项目是图书馆吗?如果是这样:否

可以在 this GitHub issue 中找到对此更详细的描述,其中 Yarn 的创建者之一,例如。说:

package.json 描述了原作者想要的预期版本,而 yarn.lock 描述了给定应用程序的最后一个正确的配置。

只会使用顶级项目的 yarn.lock 文件。因此,除非某个项目将单独使用而不安装到另一个项目中,否则提交任何 yarn.lock-file  是没有用的——相反,它始终取决于 package.json-file 来传达哪些版本的依赖项项目预计然后。


另一方面,库项目中没有锁定文件会影响它们各自测试的可重复性吗?
如果我正确阅读了您的描述,而不是“您的项目是图书馆吗?”可以用“如果你愿意”来回答。它似乎没有缺点,但如果你有复杂的 devDependencies 并且你希望你的 lib 的每个开发人员都拥有相同的构建和测试脚本,它可能会很有用。正确的?
由于您的库的任何用户都不会尊重锁定文件,因此在开发库时依赖它可能会给人一种虚假的安全感
Dart 与 pubspec.yaml 和 pubspec.lock 具有相同的系统,并建议与答案中的相同。请参阅 this 问题和 this 文档条目。
请在 Yarn 的官方博客中查看此条目:Lock files should be committed on all projects
b
bennygenel

我看到这是两个独立的问题。让我两个都回答。

您应该将文件提交到 repo 吗?

是的。如 ckuijjer's answer 中所述,建议在 Migration Guide 中将此文件包含在 repo 中。请继续阅读以了解为什么您需要这样做。

什么是 yarn.lock

它是一个文件,用于存储项目的确切依赖版本以及每个包的校验和。这是 yarn 为您的依赖项提供一致性的方式。

要了解为什么需要此文件,您首先需要了解原始 NPM 的 package.json 背后的问题是什么。安装包时,NPM 将存储依赖项的允许修订范围,而不是特定修订 (semver)。 NPM 将尝试在指定范围内获取更新依赖最新版本的依赖(即不间断的补丁更新)。这种方法有两个问题。

依赖关系作者可能会发布补丁版本更新,而实际上会引入会影响您的项目的重大更改。两个在不同时间运行 npm install 的开发人员可能会得到不同的依赖集。这可能会导致错误在两个完全相同的环境中无法重现。例如,这可能会导致 CI 服务器的构建稳定性问题。

另一方面,纱线采用最大可预测性的路线。它创建 yarn.lock 文件以保存 exact 依赖项版本。放置该文件后,yarn 将使用存储在 yarn.lock 中的版本,而不是解析来自 package.json 的版本。该策略保证不会发生上述任何问题。

yarn.lock 类似于 npm-shrinkwrap.json,可以通过 npm shrinkwrap 命令创建。检查 this answer 解释这两个文件之间的差异。


但我看到 yarn.lock 时不时地更新,您知道 yarn 为何以及何时更新吗?
纱线问题 #4379#4147 建议 yarn 在许多情况下更新 yarn.lock,包括在不更改 package.json 的情况下运行 yarn install。按照 Why does running yarn on windows changes yarn.lock 中的建议使用 yarn install --frozen-lockfile(或通过 .yarnrc 配置)似乎是最好的选择。
现在的 npm 有一个 package-lock.json 和一个 npm ci。该工作流程类似于 yarn 的 yarn.lockyarn install --frozen-lockfile
k
k0pernikus

你应该:

将其添加到存储库并提交它使用 yarn install --frozen-lockfile 而不是 yarn install 作为本地和 CI 构建服务器上的默认值。

(我在 yarn 的问题跟踪器上打开了一张票,以提出使 freeze-lockfile 成为默认行为的案例,请参阅 #4147)。

注意不要在 .yarnrc 文件中设置 frozen-lockfile 标志,因为这会阻止您同步 package.json 和 yarn.lock 文件。请参阅相关的yarn issue on github

yarn install may mutate your yarn.lock unexpectedly,使可重复构建的纱线声明无效。您应该只使用 yarn install 来初始化 yarn.lock 并更新它。

另外,特别是。在较大的团队中,您可能会因为开发人员正在设置他们的本地项目而对纱线锁的更改产生很多噪音。

如需更多信息,请阅读 my answer about npm's package-lock.json,因为这也适用于此处。

最近在 docs for yarn install 中也明确了这一点:

yarn install 在本地 node_modules 文件夹中安装 package.json 中列出的所有依赖项。 yarn.lock 文件的使用如下:如果存在 yarn.lock 并且足以满足 package.json 中列出的所有依赖项,则安装 yarn.lock 中记录的确切版本,并且 yarn.lock 将保持不变。 Yarn 不会检查更新的版本。如果没有 yarn.lock,或者不足以满足 package.json 中列出的所有依赖项(例如,如果您手动将依赖项添加到 package.json),Yarn 会查找满足 package.json 约束的最新可用版本.json。结果写入yarn.lock。如果要确保不更新 yarn.lock,请使用 --frozen-lockfile。


虽然确实如此,但我认为您必须使用 --frozen-lockfile 的唯一情况是有人手动更新了 package.json 而没有随后运行 yarn install 并提交更新。因此 CI 可能想要使用该标志,但开发人员不应该因为它隐藏了问题。
@jkrehm 取决于隐藏问题的含义。我遇到了更多由 yarn install 引入的意外更改的 yarn.lock 文件的麻烦,无论是通过膨胀的拉取请求,还是通过导致不必要的合并冲突,或者通过拉动一个破坏性的库。 (仅仅因为库使用 semvar,并不意味着补丁/次要更新不会破坏您的应用程序——我去过那里)。我认为更新 yarn.lock 应该只是一个手动步骤,这就是为什么我依赖 yarn install --frozen-lockfile(以及 npm 项目上的 npm ci)甚至在我的开发机器上,因为它是可靠且确定的。
我从来没有遇到过 yarn.lock 意外更新的问题(自 2016 年 10 月发布以来一直在使用)。一直是用户手动执行某些操作或糟糕的安装后脚本。这就是我更喜欢 Yarn 而不是 NPM 的原因(NPM 会随时更新它想要的所有内容)。我想我会认为自己很幸运没有遇到这些问题。
A
Anshul

根据我的经验,我会说是的,我们应该提交 yarn.lock 文件。它将确保当其他人使用您的项目时,他们将获得与您的项目预期相同的依赖项。

From the Doc

当您运行 yarn 或 yarn add 时,Yarn 将在包的根目录中生成一个 yarn.lock 文件。您无需阅读或理解此文件 - 只需将其签入源代码管理即可。当其他人开始使用 Yarn 而不是 npm 时,yarn.lock 文件将确保他们获得与您完全相同的依赖项。

一种争论可能是,我们可以通过将 ^ 替换为 -- 来实现它。是的,我们可以,但总的来说,我们已经看到大多数 npm 包都带有 ^ 符号,我们必须手动更改符号以确保静态依赖版本。但如果您使用 yarn.lock,它将以编程方式确保您的正确的版本。

也正如 Eric Elliott 所说here

不要 .gitignore yarn.lock。它可以确保确定性的依赖解决方案,以避免“在我的机器上工作”错误。


另一个考虑因素:github 可以从 .lock 中发现安全问题,因此您可以为您的应用程序部署快速更新。
j
jarekwg

我猜是的,因为 Yarn 版本有自己的 yarn.lock 文件:https://github.com/yarnpkg/yarn

它用于确定性包依赖解析。


n
nerdlinger

不要扮演魔鬼的拥护者,但我(多年来)慢慢地意识到你不应该提交锁定文件的想法。

我知道他们所说的每一点文件都说你应该这样做。但这能有什么好处呢?!在我看来,缺点远远大于好处。

基本上,我花了无数个小时来调试最终通过删除锁定文件解决的问题。例如,锁定文件可能包含有关要使用哪个包注册表的信息,并且在不同用户访问不同注册表的企业环境中,这是灾难的根源。

此外,锁定文件确实会弄乱您的依赖关系树。因为 yarn 和 npm 创建了一个复杂的树,并且将不同版本的外部模块保存在不同的位置(例如,在应用程序顶部 node_modules 文件夹中的模块内的 node_modules 文件夹中),如果您频繁更新依赖项,它会造成真正的混乱。再一次,我花了很多时间试图找出一个模块的旧版本仍然在一个依赖项中使用,其中模块版本已经更新,只是发现删除锁定文件和 node_modules 文件夹解决了所有困难- 诊断问题。

现在我什至有 shell 别名,可以在运行 yarn 或 npm 之前删除锁定文件(有时也删除 node_modules 文件夹!)。

我猜只是硬币的另一面,但盲目地遵循这个教条可能会让你付出代价......


“不同用户访问不同注册表的企业环境”我认为这本身就是灾难的根源。一个项目应该在所有用户之间共享相同的注册表,否则你会遇到问题。
完全同意,似乎问题出在您的企业设置上,而不是锁定文件。
这里的评论似乎忽略了一点:我们中的一些人开发是为了交付给某些企业。任何技术堆栈都应与交付模型/约束无关。由于多种原因(主要是与企业环境相关),可能会出现这种隔离。在不考虑开发人员限制的灵活性的情况下,没有办法使配置适应这些情况是一种简单的方法。
e
enapupe

是的!必须签入 yarn.lock,以便安装依赖项的任何开发人员都能获得完全相同的输出!例如,使用 npm [2016 年 10 月推出],您可以在本地安装一个 patch 版本(比如 1.2.0),而新开发人员运行新鲜的 install 可能会得到不同的版本 (1.2.1)。


您提到的 npm 行为取决于您如何保存依赖项。如果在使用 npm 时使用 --save-exact 保存,则可以实现相同的行为。
@AlicanC 我不认为这很简单。我相信纱线(通过提交的锁文件)将保证相同版本的包及其所有依赖项。这是 NPM 一直存在的问题,因为依赖项的依赖项可能不会固定到特定版本,因此新安装可能会引入不同的较低级别的依赖项。 NPM 收缩包装应该在一定程度上解决这个问题,但它总是很棘手,而且经常无法正常工作。
@nextgentech 如果在这种情况下,我如何确保正确更新依赖项的依赖项。假设我有一个包含一些(比如 3 个)依赖包的主包。我将观察我的主包中的变化并在 package.json 中更新它。但是,如果他们更新了 3 个子包中的任何一个,我将如何获得更改?由于锁定文件,这些依赖项不会被更新,对吧?
我还没有搞砸它,但我相信这就是 yarn upgrade 命令发挥作用的地方。此命令将升级所有软件包并重新创建锁定文件。因此,例如,如果您正在将应用程序部署到生产环境并需要安装依赖项,它将根据从存储库中提取的锁定文件来执行此操作。除非您明确想要更改依赖关系信息(并因此提交新的锁定文件),否则您永远不应运行 yarn upgrade
yarn install 不能确保相同的版本。只有 yarn install --frozen-lockfile 可以。
N
Navin prasad

是的,你应该提交。有关 yarn.lock 文件的更多信息,请参阅官方文档here