纱线:使用依赖的yarn.lock

use*_*344 3 lockfile npm yarnpkg

我使用yarn直接从公司的GitLab安装包:

yarn add git+ssh://<user>@<host>:<repo>

对于第一级依赖项,yarn --pure-lockfilenode_modules根据使用来重构我的yarn.lock.

但是,对于二级依赖,yarn似乎总是安装最新版本.

所以,假设我依赖于A使用特定版本测试哪个B.在A中package.json我没有指定版本,但它包含在yarn.lock.

当我现在安装包A纱线将获得最新版本B尽管进入A/yarn.lock

我知道我可以通过传递特定版本来解决这个问题A/package.json(至少我认为).

但有没有选择告诉纱线看看yarn.lock依赖关系?

yes*_*hah 6

TLDR:

在应用程序中安装依赖项时,只会考虑您自己的yarn.lock文件.您的依赖项中的锁定文件将被忽略.参考


让我们先清除一些东西:

  1. --pure-lockfile与普通纱线安装相同,只是它不会生成yarn.lock文件或更新一个文件(如果存在).
  2. yarn.lock除非提供,否则纱线在安装时始终会从默认情况下读取以解析依赖关系--no-lockfile.所以,没有必要告诉它yarn.lock.

什么yarn.lock用于?

yarn.lock用于解析version给定semver version模块的内容package.json.它用于确定semver version模块应该解析的内容.这根本不是它的用例.

正如纱线DOCS中所提到的:为了在机器之间获得一致的安装,Yarn需要的信息比您在软件包json中配置的依赖项更多.Yarn需要准确存储每个依赖项的安装版本.

为此,Yarn使用yarn.lock项目根目录中的文件.

因此,为了解决semver version依赖关系,纱线总是依赖于package.json.对于给定的semver version,纱线检查yarn.lock文件以查看version它应该获取什么.这是什么使纱线确定性(同tecknique使用由npm它使用npm-shrinkwrap.json).

示例:类似的Semver版本^1.2.4可以解析为任何版本号>= 1.2.3 and < 2.0.0.如果没有纱线,npm将安装1.2.4在一台机器上,但安装在1.9.9其他机器中,具体取决于安装时的最新版本.这是纱线解决使用的问题yarn.lock.

semver version被确定的 package.json文件.该yarn.lock文件仅查找要 为给定数字安装的版本提交哈希semver version.

鉴于其semver版本,yarn如何解析模块的版本?

假设我们的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"
Run Code Online (Sandbox Code Playgroud)
  1. 如果package.json有bluebird: "^2.9.30",则yarn bluebird@^2.9.30在lockfile中查找条目.它存在并因此被解决version=2.11.0.
  2. 如果package.json有bluebird: "^2.9.0",则yarn bluebird@^2.9.0在lockfile中查找条目.它不存在.假设满足semver标准的最新稳定版本是2.13.0,则yarn添加一个条目bluebird@^2.9.0,解析为2.13.0.在为给定semver version的bluebird 解析版本时,在lockfile中moduleA的依赖项中bluebird的条目无关紧要.

Semver Version不是受什么条目中存在的依赖关系图中的模块yarn.lock文件.

因此,如果package.json有bluebird: "",则yarn bluebird@在lockfile中查找条目但无法找到它.因此bluebird: "",假设它解析为最新版本3.5.0.现在,纱线将添加一个待bluebird@解决的条目3.5.0.

bluebird@:
  version "3.5.0"
  resolved "https://<...>/bluebird-3.5.0.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9"
Run Code Online (Sandbox Code Playgroud)

现在在纱线遇到时形成{bluebird: ""},它将bluebird@在锁定文件中找到一个条目,因此将始终将其解析为3.5.0.

解决您的问题

要解决B: ""到版本说1.0.0,你需要有一个条目B@yarn.lock决心1.0.0.有一次,yarn.lock有一个入口B@,所有的后续安装将永远取版本1.0.0B="".

以下是完成相同操作所需的步骤:

方法1(推荐)

如果您希望B解析为最新版本:

  1. 添加B:""A的package.json
  2. yarn install.这将添加一个条目以B@解析为最新版本.
  3. 推送yarn.lock文件.
  4. 从现在开始,无论谁运行yarn install都将获得相同的版本.

方法2

如果你想B有旧版本:( 强烈不推荐)

  1. 添加B: 1.0.0A的package.json.
  2. yarn install.这将B@1.0.0在lockfile中添加一个条目.
  3. 添加在yarn.lock B@旁边B@1.0.0.B@, B@1.0.0: ...
  4. 将B的版本更改为""A的package.json.
  5. 推送yarn.lock文件.
  6. 从现在开始,无论谁跑,yarn install都会得到B的版本1.0.0.

这种方法非常危险,因为您可以轻松破坏某些东西.您的yarn.lock文件应始终由yarn管理.

方法3(推荐)

如果你想让B保持在1.0.0

  1. 将B的版本修复到1.0.0A的package.json中.
  2. yarn install.这将B@1.0.0在lockfile中添加一个条目.
  3. 推yarn.lock文件
  4. 从现在开始,无论谁跑,yarn install都会得到B的版本1.0.0.

编辑:使用依赖项中存在的yarn.lock文件

如果你查看这个doc:,他们已经清楚地提到纱线将只使用顶级 yarn.lock文件并忽略依赖项中存在的锁文件.

目前无法使用其中存在的yarn.lock锁定第二级依赖项.我认为没有必要.事实上,纱线的创造者在这里解释为什么会这样.原因是:

  1. 如上所述,顶层yarn.lock文件可以很好地捕获为二级依赖项安装的版本.
  2. 直接使用它们时,您永远无法更新自己应用程序中的子依赖项版本,因为它们会被其他yarn.lock文件锁定.您可以通过我对纱线如何解析依赖关系的解释来验证这一点.
  3. Yarn永远无法折叠(去重复)依赖项,因此兼容的版本范围只能安装单个版本.

此外,如在您的用例中,如果A具有仅适用于版本的依赖关系B 1.0.0,则A的package.json应该具有针对B 1.0.0而不是"" 提及的版本.您可以随时修复顶级yarn.lock以添加要B@解析的条目,1.0.0但不建议手动修复yarn.lock文件,如上所述.

希望这有帮助!如有任何疑问,请在评论中告诉我.