Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I override nested dependencies with `yarn`?

If my package has these dependencies

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

And the foobar package has these dependencies

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

and the most recently released version of baz is 2.1.0, the first run of yarn will install [email protected] in foobar/node_modules.

How do I force yarn to use the [email protected] package for foobar?

My understanding is that this would be possible using 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?

like image 466
Chris W. Avatar asked Oct 24 '16 20:10

Chris W.


People also ask

How do you remove a dependency from a yarn lock?

If you run yarn remove [package] it will remove the package from node_modules and also from the yarn. lock file. If you manually delete from package. json and then run yarn install , the deleted package is not installed and the yarn.

How do you update all dependencies with yarn?

just run yarn upgrade-interactive --latest and select packages you want to update using space button and press the enter to update. Show activity on this post. Change all your dependencies to a fixed version ( "x.x.x" )

How do I remove npm nested dependency?

If you're using npm : Run npm dedupe after installing packages to remove nested duplicates. You can try deleting your package-lock. json and do a fresh install.


2 Answers

If you do in fact have a sub-dependency that is overly restrictive in what versions it will accept, you can override them using yarn.

UPDATED EDIT: Yarn now, as of 1.0, officially supports the "resolutions" block. So the way to override resolutions is to just add a block like this to 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 overly restrictive in what version they accept, and so I'll happily select the latest version when it doesn't actually break things.

Original but outdated answer below.

It sounds like the original question wasn't exactly correct, but the original question was in 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-emitter as 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:

[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:

[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 --flat option, 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 work correctly.

But in the docs to yarn --flat I found a reference to a "resolutions" block that can go in 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.

(And now the resolutions block is completely supported in yarn, so you don't even need to use --flat.)

like image 50
SomeCallMeTim Avatar answered Sep 17 '22 11:09

SomeCallMeTim


This is now possible with yarn's selective version resolution feature.

In your project's package.json, use 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.

like image 23
Tom Hale Avatar answered Sep 20 '22 11:09

Tom Hale