如何使用 `yarn` 覆盖嵌套依赖项?

How do I override nested dependencies with `yarn`?

如果我的包有这些依赖项

{ "name": "my-package",
  "dependencies": { "foobar":"~1.0.3", "baz":"2.0.9" }

并且 foobar 包具有这些依赖项

{ "name": "foobar",
  "dependencies": { "baz":"^2.0.0" }

并且 baz 的最新发布版本是 2.1.0yarn 的第一个 运行 将在 foobar/node_modules 中安装 baz@2.1.0 .

如何强制 yarn 使用 foobarbaz@2.0.9 包?

我的理解是,使用 npm shrinkwrap(la this question)是可能的。


我的问题的总结可能是:Yarn 创建可重复的、确定性的安装,但我如何自定义该安装?

如果您确实有一个子依赖项,该子依赖项在接受的版本方面受到过度限制,您可以使用 yarn 覆盖它们。

更新编辑: Yarn 现在,从 1.0 开始,officially supports "resolutions" 块。因此,覆盖分辨率的方法是将这样的块添加到 package.json:

"resolutions": {
      "package-a": "2.0.0",
      "package-b": "5.0.0",
      "package-c": "1.5.2"
}

你有时会收到 "incompatible" 版本的警告,但我发现有些软件包(如 socket.io)在它们的版本中 过度 限制接受,所以我很乐意 select 最新版本,因为它实际上并没有破坏东西。

下面是原始但已过时的答案。

原来的问题听起来不完全正确,但原来的问题实际上是我想要回答的问题,我找到了答案,所以在这里为子孙后代:

我正在使用 socket.io 库,它有 component-emitter 作为依赖项。但它有一对它需要的版本。这是我更改任何内容之前 yarn.lock 文件的样子:

component-emitter@1.1.2:
  version "1.1.2"
  resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.1.2.tgz#296594f2753daa63996d2af08d15a95116c9aec3"

component-emitter@1.2.0:
  version "1.2.0"
  resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.0.tgz#ccd113a86388d06482d03de3fc7df98526ba8efe"

所以它在我的客户端代码中包含了组件发射器的两个副本。我看了看,在 1.1.2 和 1.2.0(或当前的 1.2.1)之间似乎没有任何重大变化。我首先尝试更改 yarn.lock 文件:

component-emitter@1.2.1, component-emitter@^1.2.1, component-emitter@1.1.2:
  version "1.2.1"
  resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6"

这行得通,但是该文件有关于它是自动生成的警告,这意味着我添加的每个更新或新包都会影响此更改。稍微搜索找到 yarn --flat 选项,这将强制 yarn 在整个项目中的每个包中选择不超过一个。这对我来说似乎有点矫枉过正,因为我确信确实存在新旧软件包之间不兼容的实际情况。我只是想从我的客户端代码中删除一个冗余包,以使下载更小;我仍然希望所有开发包都能 正常工作

但是在 yarn --flat 的文档中我找到了对 "resolutions" 块的引用,它可以进入 package.json:

"resolutions": {
  "package-a": "2.0.0",
  "package-b": "5.0.0",
  "package-c": "1.5.2"
}

所以我尝试将 "component-emitter" : "1.2.1" 放入我的 package.json 中的一个新的 "resolutions" 块中,实际上它在所有需要它的地方将组件发射器扁平化为 1.2.1,现在我的客户端代码中只有一份。

(现在 yarn 完全支持 resolutions 块,所以你甚至不需要使用 --flat。)

编辑:现在已弃用,请改为阅读此答案:


@SomeCallMeTime's 很棒,我们在工作中已经这样做了一个月。

不幸的是,自 v0.24.x(见 comment)以来,这不再可能了。

有一个开放的 PR on Github 有一个 RFC 提案,它有一个简单的方法来处理该用例,而不必关注生成的锁定文件。

yarn 的 selective version resolution feature 现在可以做到这一点。

在您项目的 package.json 中,使用 resolutions:

  "resolutions": {
    "foobar/**/baz": "2.0.9"
  }

这会覆盖包 foobar(以及它下面的任何其他包)的 baz 版本,迫使它成为版本 2.0.9。