Yarn:使用 yarn.lock 的依赖
Posted
技术标签:
【中文标题】Yarn:使用 yarn.lock 的依赖【英文标题】:Yarn: use yarn.lock of dependencies 【发布时间】:2018-08-29 01:05:33 【问题描述】:我使用 yarn 直接从公司的 GitLab 安装包:
yarn add git+ssh://<user>@<host>:<repo>
对于一级依赖,我使用yarn --pure-lockfile
根据yarn.lock
重构我的node_modules
。
但是,对于二级依赖,yarn 似乎总是安装最新版本。
假设我依赖A
,它使用特定版本的B
进行了测试。在A的package.json
中我没有指定版本,但它包含在yarn.lock
中。
当我现在安装包A
时,尽管A/yarn.lock
中有条目,但纱线将获得最新版本的B
我知道我可以通过在 A/package.json
中传递特定版本来解决这个问题(至少我认为)。
但是是否有一个选项可以告诉 yarn 查看依赖项的yarn.lock
?
【问题讨论】:
我们也有类似的事情。我们有一个构建工具,我们将其作为库分发。依赖项的数量(其中大部分是可传递的)是巨大的。 【参考方案1】:TLDR:
当你在你的 应用程序,仅尊重您自己的 yarn.lock 文件。锁定文件 在您的依赖项中将被忽略。 Reference
让我们先把一些事情弄清楚:
--pure-lockfile
与正常的 yarn 安装相同,只是它不会生成 yarn.lock
文件或更新一个(如果存在)。
默认情况下,Yarn 总是从 yarn.lock
读取以在安装时解决依赖关系,除非提供 --no-lockfile
。因此,没有必要告诉它从yarn.lock
读取。
yarn.lock
是做什么用的?
yarn.lock
用于解析应该获取的version
给定package.json
中模块的semver version
。它不用于确定应将模块解析为什么semver version
。那根本不是它的use-case。
如 yarn DOCS 中所述:为了保持一致 跨机器安装,Yarn 需要的信息比 您在包 json 中配置的依赖项。纱线需要 store 确切地安装了每个依赖项的哪些版本。
为此,Yarn 使用项目根目录中的
yarn.lock
文件。
因此,为了解决依赖关系的semver version
,yarn 始终依赖于package.json
。对于给定的semver version
,yarn 检查yarn.lock
文件以查看它应该获取什么version
。这就是纱线 Deterministic 的原因(npm
使用相同的技术,它使用 npm-shrinkwrap.json
)。
示例:像^1.2.4
这样的Semver 版本可以解析为>= 1.2.3 and < 2.0.0
的任何版本号。如果没有 yarn,npm 将在一台机器上安装 1.2.4
,但在另一台机器上安装 1.9.9
,这取决于安装时存在的 最新 版本。这是yarn使用yarn.lock
解决的问题。
semver version
由package.json
文件。yarn.lock
文件只是一个查找 version 和 commit hash 为给定的semver version
号码安装。
根据模块的 semver 版本,纱线如何解析模块的版本?
假设当前我们的 yarn.lock 文件如下所示:
bluebird@2.9.6:
version "2.9.6"
resolved "https://<...>/bluebird-2.9.6.tgz#1fc3a6b1685267dc121b5ec89b32ce069d81ab7d"
bluebird@^2.9.30:
version "2.11.0"
resolved "https://<...>/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1"
...
myModule@5.1.0:
version "5.1.0"
resolved "https://<...>/moduleA-5.1.0.tgz#ce97130858add59d616ee80675383b0c127290a0"
dependencies:
bluebird "^1.0.0"
-
如果 package.json 有
bluebird: "^2.9.30"
,yarn 会在锁文件中查找 bluebird@^2.9.30
条目。它存在,因此被解析为version=2.11.0
。
如果 package.json 有bluebird: "^2.9.0"
,yarn 会在锁文件中查找bluebird@^2.9.0
条目。它不存在。假设满足 semver 标准的最新稳定版本是2.13.0
,那么 yarn 为bluebird@^2.9.0
添加一个条目,解析为2.13.0
。在解析给定蓝鸟 semver version
的版本时,锁定文件中模块 A 的依赖项中的蓝鸟条目并不重要。
Semver Version
不受条目的影响 存在于yarn.lock
文件中的模块的依赖关系图中。
所以,如果 package.json 有 bluebird: ""
,yarn 会在 lockfile 中查找条目 bluebird@
,但无法找到它。因此,它将bluebird: ""
解析为最新版本,假设3.5.0
。现在,yarn 将为bluebird@
添加一个条目,解析为3.5.0
。
bluebird@:
version "3.5.0"
resolved "https://<...>/bluebird-3.5.0.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9"
当 yarn 遇到 bluebird: ""
时,Form 现在会在锁定文件中找到 bluebird@
的条目,因此将始终将其解析为 3.5.0
。
您的问题的解决方案
要将B: ""
解析为版本1.0.0
,您需要将yarn.lock
中的B@
条目解析为1.0.0
。曾经,yarn.lock
有一个 B@
的条目,所有后续安装将始终为 B=""
获取版本 1.0.0
。
您需要采取以下步骤来完成相同的操作:
方法 1(推荐)
如果你想让 B 解析到最新版本:
-
在A的package.json中添加
B:""
运行yarn install
。这将为 B@
添加一个条目,解析为最新版本。
推送yarn.lock
文件。
现在打开表单,运行yarn install
的人将获得相同的版本。
方法 2
如果您希望 B 拥有旧版本:(强烈不推荐)
-
在A的package.json中添加
B: 1.0.0
。
运行yarn install
。这将在锁定文件中添加一个条目B@1.0.0
。
在 yarn.lock 中添加 B@
和 B@1.0.0
。 B@, B@1.0.0: ...
在 A 的 package.json 中将 B 的版本更改为 ""
。
推送yarn.lock
文件。
现在打开表格,运行yarn install
的人将获得B 的版本为1.0.0
。
这种方法非常危险,因为您很容易破坏某些东西。您的 yarn.lock 文件应始终为 managed by yarn。
方法 3(推荐)
如果你想让 B 保持在 1.0.0
-
在 A 的 package.json 中将 B 的版本修复为
1.0.0
。
运行yarn install
。这将在锁定文件中添加一个条目B@1.0.0
。
推送 yarn.lock 文件
现在打开表格,运行yarn install
的人将获得B 的版本为1.0.0
。
编辑:使用依赖项中的 yarn.lock 文件
如果你查看doc:,他们已经明确提到,yarn 将仅使用*** yarn.lock 文件并忽略依赖项中存在的锁定文件。
目前无法使用其中存在的 yarn.lock 锁定二级依赖项。我认为没有必要。事实上,纱线的创造者解释了here为什么会这样。原因是:
-
二级依赖安装的版本可以是
正如我所解释的,由*** yarn.lock 文件很好地捕获
以上。
如果直接使用子依赖项,您将永远无法在在您自己的应用程序中更新它们的版本,因为它们会被其他 yarn.lock 文件锁定。您可以验证这一点通过我对纱线如何解决依赖关系的解释。
Yarn 永远无法折叠(消除重复)依赖项,因此兼容的版本范围只能安装一个版本。
此外,在您的用例中,如果 A 具有仅适用于版本 1.0.0
的依赖项 B,则 A 的 package.json 应该将 B 的版本提到为 1.0.0
而不是“”。您始终可以修复您的***yarn.lock
以添加解析为1.0.0
的B@
条目,但不建议手动修复yarn.lock 文件,如上所述。
希望这有帮助!如有任何疑问,请在 cmets 中联系我。
【讨论】:
首先感谢您非常好的回答。然而,这不是在现实世界中可用的解决方案。实际的问题是我们有一个库(A),我们可以在其中指定一个具有固定版本(1.0.0)的依赖项(B),但是 B 本身也有可能没有被锁定的依赖项。 糟糕,意外发送...无论如何。我们单独测试了 A,这意味着它有一个 yarn.lock 文件,其中包含我们确信它可以使用的所有传递依赖项。现在我们想将 A 与它的所有依赖项的版本一起使用,如其锁定文件中指定的那样。 “我认为没有必要。” - 一旦您的传递依赖项之一违反了 semver 规则,您就会看到需要。唯一不需要的语言(我知道的)是 Elm,它有一个检查 semver 的编译器。在我们的一个库中,我们有一个将近 10.000 行的锁定文件,即使几率很小,也会发生损坏。 我明白你的意思。但是看看这个:yarnpkg.com/blog/2016/11/24/lockfiles-for-all 根据 James Kyle 的说法,当您在应用程序中安装依赖项时,只有您自己的 yarn.lock 文件受到尊重。依赖项中的锁定文件将被忽略。 还在我的回答中添加了一个编辑以反映这些理解。希望这会有所帮助。以上是关于Yarn:使用 yarn.lock 的依赖的主要内容,如果未能解决你的问题,请参考以下文章
Yarn:将 JavaScript 依赖项重新部署到生产服务器的过程(使用 `yarn.lock` 文件)