TLDR:
当您在应用程序中安装依赖项时,仅尊重您自己的 yarn.lock 文件。依赖项中的锁定文件将被忽略。参考
让我们先弄清楚一些事情:
--pure-lockfile与正常的 yarn install 相同,只是它不会生成yarn.lock文件或更新文件(如果存在)。
- Yarn 在安装时总是从默认情况下读取
yarn.lock以解决依赖关系,除非随--no-lockfile. 所以,没有必要告诉它从yarn.lock.
是yarn.lock用来做什么的?
yarn.lock用于解决给version定. 它不用于确定应将模块解析为什么。那根本不是它的用例。semver versionpackage.jsonsemver 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.lock1.0.0yarn.lockB@1.0.0B=""
以下是您需要采取的步骤来完成相同的操作:
方法 1(推荐)
如果您希望 B 解析为最新版本:
- 添加
B:""A的package.json
- 运行
yarn install。这将添加一个已B@解析到最新版本的条目。
- 推送
yarn.lock文件。
- 现在就形成,无论谁运行,
yarn install都会得到相同的版本。
方法二
如果您希望 B 拥有旧版本:(强烈不推荐)
- 添加
B: 1.0.0A的package.json。
- 运行
yarn install。这将在锁定文件中添加一个条目B@1.0.0。
- 在 yarn.lock
B@旁边添加。B@1.0.0B@, 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.0A 的 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 文件,正如我上面提到的。
希望这有帮助!如有任何疑问,请在评论中联系我。