node.js 如何使用`yarn`覆盖嵌套依赖项?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40226639/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I override nested dependencies with `yarn`?
提问by Chris W.
If my package has these dependencies
如果我的包有这些依赖
{ "name": "my-package",
"dependencies": { "foobar":"~1.0.3", "baz":"2.0.9" }
And the foobarpackage has these dependencies
并且该foobar包具有这些依赖项
{ "name": "foobar",
"dependencies": { "baz":"^2.0.0" }
and the most recently released version of bazis 2.1.0, the first run of yarnwill install [email protected]in foobar/node_modules.
和最新发布的版本baz是2.1.0,第一次运行yarn将安装[email protected]在foobar/node_modules.
How do I force yarn to use the [email protected]package for foobar?
如何强制纱线使用[email protected]包装foobar?
My understanding is that this would be possible using npm shrinkwrap(a la this question).
我的理解是这可以使用npm shrinkwrap(a la this question)。
The summary of my question probably is: Yarn creates repeatable, deterministic installations, but how do I customize that installation?
我的问题的总结可能是:Yarn 创建可重复的、确定性的安装,但我如何自定义该安装?
回答by SomeCallMeTim
If you do in fact have a sub-dependency that is overly restrictive in what versions it will accept, you canoverride them using yarn.
如果您确实有一个子依赖项,它接受的版本过于严格,您可以使用 yarn 覆盖它们。
UPDATED EDIT:Yarn now, as of 1.0, officially supportsthe "resolutions" block. So the way to override resolutions is to just add a block like this to package.json:
更新编辑:从 1.0 开始,Yarn 现在正式支持“分辨率”块。因此,覆盖分辨率的方法是将这样的块添加到package.json:
"resolutions": {
"package-a": "2.0.0",
"package-b": "5.0.0",
"package-c": "1.5.2"
}
You'll get warnings for "incompatible" versions sometimes, but I find that some packages (like socket.io) are overlyrestrictive in what version they accept, and so I'll happily select the latest version when it doesn't actually break things.
有时您会收到“不兼容”版本的警告,但我发现某些软件包(如 socket.io)在它们接受的版本方面过于严格,因此当它实际上没有损坏时,我会很乐意选择最新版本事物。
Original but outdated answer below.
下面的原始但过时的答案。
It sounds like the original question wasn't exactly correct, but the original question wasin fact the one I wanted answered, and I found an answer, so here it is for posterity:
这听起来像原来的问题是不完全正确的,但原来的问题是实际上是一个我想回答,我找到了答案,所以这里是为后人:
I'm using the socket.io library, and it has component-emitteras a dependency. But it has a pair of versions that it requires. This is what the yarn.lock file looked like before I changed anything:
我正在使用 socket.io 库,它有component-emitter一个依赖项。但它有一对它需要的版本。这是我更改任何内容之前 yarn.lock 文件的样子:
[email protected]:
version "1.1.2"
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.1.2.tgz#296594f2753daa63996d2af08d15a95116c9aec3"
[email protected]:
version "1.2.0"
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.0.tgz#ccd113a86388d06482d03de3fc7df98526ba8efe"
So it was including two copies of the component emitter in my client code. I looked, and there didn't appear to be any breaking changes between 1.1.2 and 1.2.0 (or 1.2.1, which was current). I first tried just changing the yarn.lock file:
所以它在我的客户端代码中包含了组件发射器的两个副本。我看了看,1.1.2 和 1.2.0(或当前的 1.2.1)之间似乎没有任何重大变化。我首先尝试更改 yarn.lock 文件:
[email protected], component-emitter@^1.2.1, [email protected]:
version "1.2.1"
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6"
This worked, but the file has warnings about it being autogenerated, meaning that every single update or new package I add will stomp on this change. A bit of searching found the yarn --flatoption, which will force yarn to choose no more than one of each package in the entire project. That seems like overkill to me, since I'm sure there are actual cases of incompatibility between older and newer packages. I just wanted to eliminate a redundant package from my client code, to make the download smaller; I still want the development packages to all workcorrectly.
这有效,但该文件有关于它是自动生成的警告,这意味着我添加的每个更新或新包都会踩到这个更改。一点搜索找到了yarn --flat选项,这将迫使纱线在整个项目中选择不超过一个包。这对我来说似乎有点矫枉过正,因为我确信新旧软件包之间存在不兼容的实际情况。我只是想从我的客户端代码中删除一个冗余包,使下载更小;我仍然希望开发包都能正常工作。
But in the docs to yarn --flatI found a reference to a "resolutions" block that can go in package.json:
但是在yarn --flat的文档中,我发现了一个对“分辨率”块的引用,该块可以放在 package.json 中:
"resolutions": {
"package-a": "2.0.0",
"package-b": "5.0.0",
"package-c": "1.5.2"
}
So I tried putting "component-emitter" : "1.2.1"in a new "resolutions" block in my package.json, and it in fact flattened component-emitter to 1.2.1 for all places that required it, and now I have only one copy in my client code.
所以我尝试"component-emitter" : "1.2.1"在我的 package.json 中放入一个新的“分辨率”块,它实际上将所有需要它的地方的组件发射器扁平化为 1.2.1,现在我的客户端代码中只有一个副本。
(And now the resolutionsblock is completely supported in yarn, so you don't even need to use --flat.)
(现在该resolutions块在 中完全受支持yarn,因此您甚至不需要使用--flat。)
回答by Tom Hale
This is now possible with yarn's selective version resolution feature.
这现在可以通过 yarn 的选择性版本解析功能实现。
In your project's package.json, use resolutions:
在您的项目中package.json,使用resolutions:
"resolutions": {
"foobar/**/baz": "2.0.9"
}
This overrides package foobar's (and any other packages under it) version of baz, forcing it to be version 2.0.9.
这会覆盖 packagefoobar的(及其下的任何其他包)版本baz,强制其为 2.0.9 版。
回答by maxime1992
@SomeCallMeTime's answeris great and we've been doing that for month at work.
@SomeCallMeTime的回答很棒,我们已经工作了一个月。
Unfortunately, this is not possible anymore since the v0.24.x(see that comment).
不幸的是,从 v0.24.x 开始,这不再可能(请参阅该评论)。
There's an opened PR on Githubwith an RFC proposal to have a simple way of handling that use case without having to keep an eye on the generated lockfile.

