Yarn: resolutions is not behaving the way I expect it to

Created on 30 Apr 2018  路  12Comments  路  Source: yarnpkg/yarn

Do you want to request a feature or report a bug?
I don't know if this is a bug, a small feature request or a big feature request.
It is a request for change, however.

What is the current behavior?
Resolutions only work within semver range and do not override a package's preferred semver range.

What is the expected behavior?
A resolution is strictly enforced across all (sub-)dependencies of a project.

Please mention your node.js, yarn and operating system version.
Yarn 1.6.0
Node 8.11.1
Mac OS X (insert long version number here; up to date at the time of writing)

To illustrate my problem
Given the following excerpt from my yarn.lock:

puppeteer@^1.3.0:
  version "1.3.0"
  resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-1.3.0.tgz#f571c5f27153ca164a8188e6328ce2e4946878f3"
  dependencies:
    debug "^2.6.8"
    extract-zip "^1.6.5"
    https-proxy-agent "^2.1.0"
    mime "^1.3.4"
    progress "^2.0.0"
    proxy-from-env "^1.0.0"
    rimraf "^2.6.1"
    ws "^3.0.0"

extract-zip@^1.6.5:
  version "1.6.6"
  resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.6.tgz#1290ede8d20d0872b429fd3f351ca128ec5ef85c"
  dependencies:
    concat-stream "1.6.0"
    debug "2.6.9"
    mkdirp "0.5.0"
    yauzl "2.4.1"

mkdirp 0.5.0 does not run on strict mode (which is enforced by Jest), and results in a crash. mkdirp fixed this in 0.5.1, but extract-zip is requiring 0.5.0 and has not been updated in a very long time: https://github.com/maxogden/extract-zip/issues/57

As such, I _must_ make sure mkdirp resolves to 0.5.1, so I added a resolution:

  "resolutions": {
    "mkdirp": "^0.5.1"
  }

But this did not do anything, as yarn still respects extract-zip's wishes. At this point, I can do two things:

1: Manually edit yarn.lock and hope for the best
2: Fork extract-zip and update the dependencies, then fork puppeteer and let it use my fork of extract-zip and then use my fork of puppeteer in my project. Every time puppeteer updates, I'd need to pull it down into my fork and then re-update my project.

Both options are unwieldy. I would like to have to way to completely ignore extract-zip's wishes (demands) and force it to use a version of my choosing.

triaged

Most helpful comment

Unfortunately I'd go so far as to describe the example on that page as incoherent. What c-1 and d2-1 stand for is anyone's guess as is why there are two *s on one of them but not on the other and what the file is referring to, all a mystery.

All 12 comments

To illustrate what I was expecting resolutions to do:

Before manual editing:

[email protected]:
  version "0.3.0"
  resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e"

[email protected]:
  version "0.5.0"
  resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.0.tgz#1d73076a6df986cd9344e15e71fcc05a4c9abf12"
  dependencies:
    minimist "0.0.8"

[email protected], [email protected], "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1:
  version "0.5.1"
  resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
  dependencies:
    minimist "0.0.8"

After manual editing:

[email protected], [email protected], [email protected], [email protected], "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1:
  version "0.5.1"
  resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
  dependencies:
    minimist "0.0.8"

This is expected behavior. What you need is

  "resolutions": {
    "**/mkdirp": "^0.5.1"
  }

See the docs for more info: https://yarnpkg.com/en/docs/selective-version-resolutions/#toc-how-to-use-it

Ah, so the resolution "mkdirp" would only apply to direct dependencies; without recursing down the tree. Yeah, if explained like that it makes perfect sense!

However, even after re-reading the docs, this is not clear to me. I'll see if I can find the time sometime soon to propose an update to the docs :-)

I'll see if I can find the time sometime soon to propose an update to the docs :-)

This would be great, thank you!

Unfortunately I'd go so far as to describe the example on that page as incoherent. What c-1 and d2-1 stand for is anyone's guess as is why there are two *s on one of them but not on the other and what the file is referring to, all a mystery.

Ah, apparently I completely forgot about this. Will add it back into my agenda.

@roberthchapman it's a glob, but I guess for Windows users this may be something they've never seen before indeed. This could indeed also benefit from some examples being listed.

@StephanBijzitter is there any update on adding examples to the yarn resolutions docs? :)

Ghehe, yeah: it got lost in a huge list of things still to do.

But, I got time this morning!

@shui91 Not sure why you asked, but if it was because you'd be able to pick it up otherwise: good, because I could use your feedback on the pull request linked above 馃懠

The package.json#resolutions docs add a link to the RFC.

Perhaps it would make sense to link it here as well?

This is expected behavior. What you need is

  "resolutions": {
    "**/mkdirp": "^0.5.1"
  }

See the docs for more info: https://yarnpkg.com/en/docs/selective-version-resolutions/#toc-how-to-use-it

I know this one is almost 2 years old but isn't "**/mkdirp": "^0.5.1" the same as "mkdirp": "^0.5.1" as it is written here: https://github.com/yarnpkg/rfcs/blob/master/implemented/0000-selective-versions-resolutions.md ?

a is an alias for **/a (for retro-compatibility, see below, and because if it wasn't such an alias, it wouldn't mean anything as it would represent one of the non-nested project dependencies, which can't be overridden as explained below).

cc: @StephanBijzitter @BYK

I'm glad I wasn't the only one perplexed by those examples 馃槼

Was this page helpful?
0 / 5 - 0 ratings