TLDR:
当您在应用程序中安装依赖项时,仅尊重您自己的 yarn.lock 文件。依赖项中的锁定文件将被忽略。参考
让我们先弄清楚一些事情:
--pure-lockfile
与正常的 yarn install 相同,只是它不会生成yarn.lock
文件或更新文件(如果存在)。
- Yarn 在安装时总是从默认情况下读取
yarn.lock
以解决依赖关系,除非随--no-lockfile
. 所以,没有必要告诉它从yarn.lock
.
是yarn.lock
用来做什么的?
yarn.lock
用于解决给version
定. 它不用于确定应将模块解析为什么。那根本不是它的用例。semver version
package.json
semver version
正如yarn DOCS中提到的:为了在机器上获得一致的安装,Yarn 需要比您在包 json 中配置的依赖项更多的信息。Yarn 需要准确存储每个依赖项的安装版本。
为此,Yarn 使用yarn.lock
项目根目录中的文件。
因此,为了解决semver version
依赖关系,yarn 总是依赖于package.json
. 对于给定的semver version
,yarn 检查yarn.lock
文件以查看version
它应该获取什么。这就是纱线确定性npm
的原因(使用相同的技术npm-shrinkwrap.json
)。
示例:Semver Versions like^1.2.4
可以解析为任何版本号,即>= 1.2.3 and < 2.0.0
. 如果没有 yarn,npm 将安装1.2.4
在一台机器上,但安装在另一台1.9.9
机器上,具体取决于安装时存在的最新版本。这是 yarn 使用yarn.lock
.
由文件semver version
决定
。package.json
该yarn.lock
文件只是查找要
为给定编号安装哪个版本和提交哈希。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 会在 lockfile 中寻找一个条目bluebird@^2.9.30
。它存在,因此被解析为version=2.11.0
。
- 如果 package.json 有
bluebird: "^2.9.0"
, yarn 会在 lockfile 中寻找一个条目bluebird@^2.9.0
。它不存在。假设满足 semver 标准的最新稳定版本是2.13.0
,然后 yarn 添加一个条目 for bluebird@^2.9.0
,resolved to 2.13.0
。在为给定的 bluebird 解析版本时,semver version
在 lockfile 中 moduleA 的依赖项中为 bluebird 存在什么条目并不重要。
Semver Version
不受yarn.lock
文件中模块的依赖项映射中存在的条目的影响。
所以,如果 package.json 有bluebird: ""
, yarnbluebird@
会在 lockfile 中寻找一个条目,但找不到它。因此,它解析bluebird: ""
为最新版本,假设3.5.0
. 现在,yarn 将为bluebird@
resolve to添加一个条目3.5.0
。
bluebird@:
version "3.5.0"
resolved "https://<...>/bluebird-3.5.0.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9"
每当遇到 yarn 时{bluebird: ""}
,它都会在 lockfile 中找到一个条目bluebird@
,因此总是将其解析为3.5.0
.
解决您的问题
要解析到B: ""
版本1.0.0
,您需要有一个B@
in resolve to 的条目。一旦有 的条目,所有后续安装将始终获取的版本。yarn.lock
1.0.0
yarn.lock
B@
1.0.0
B=""
以下是您需要采取的步骤来完成相同的操作:
方法 1(推荐)
如果您希望 B 解析为最新版本:
- 添加
B:""
A的package.json
- 运行
yarn install
。这将添加一个已B@
解析到最新版本的条目。
- 推送
yarn.lock
文件。
- 现在就形成,无论谁运行,
yarn install
都会得到相同的版本。
方法二
如果您希望 B 拥有旧版本:(强烈不推荐)
- 添加
B: 1.0.0
A的package.json。
- 运行
yarn install
。这将在锁定文件中添加一个条目B@1.0.0
。
- 在 yarn.lock
B@
旁边添加。B@1.0.0
B@, B@1.0.0: ...
- 将 B 的版本更改为
""
A 的 package.json 中。
- 推送
yarn.lock
文件。
- 现在开始,运行的人
yarn install
将获得 B 的版本为1.0.0
.
这种方法非常危险,因为您可以轻松破坏某些东西。您的 yarn.lock 文件应始终由 yarn 管理。
方法 3(推荐)
如果您希望 B 保持在 1.0.0
- 将 B 的版本修复到
1.0.0
A 的 package.json 中。
- 运行
yarn install
。这将在锁定文件中添加一个条目B@1.0.0
。
- 推送 yarn.lock 文件
- 现在开始,运行的人
yarn install
将获得 B 的版本为1.0.0
.
编辑:使用依赖项中存在的 yarn.lock 文件
如果您查看此文档:,他们已经清楚地提到 yarn 将仅使用顶级yarn.lock 文件并忽略依赖项中存在的锁定文件。
目前没有办法使用它们中存在的 yarn.lock 来锁定二级依赖项。我认为没有任何必要。事实上,纱线的创造者在这里解释了为什么会这样。原因是:
- 为二级依赖安装的版本可以被顶级的 yarn.lock 文件很好地捕获,正如我在上面解释的那样。
- 直接使用它们时,您将永远无法在自己的应用程序中更新子依赖项的版本,因为它们会被其他 yarn.lock 文件锁定。您可以通过我对 yarn 如何解决依赖关系的解释来验证这一点。
- Yarn 永远无法折叠(去重)依赖项,因此兼容的版本范围只能安装一个版本。
此外,在您的用例中,如果 A 具有仅适用于 version 的依赖项 B 1.0.0
,则 A 的 package.json 应该为 B 提到版本1.0.0
而不是“”。您始终可以修复您的顶层yarn.lock
以添加一个已B@
解决的条目,1.0.0
但不建议手动修复 yarn.lock 文件,正如我上面提到的。
希望这有帮助!如有任何疑问,请在评论中联系我。