npm Community Forum (Archive)

The npm community forum has been discontinued.

To discuss usage of npm, visit the GitHub Support Community.

Wrong version is installed when dependency is specified as union range

What I Wanted to Do

Install a package that has following dependency: "redux-saga": "^1.0.0-beta.0 || ^0.16.0".
I expect this to install redux-saga@1.0.0-beta.1.

What Happened Instead

npm installs redux-saga@0.16.0

Reproduction Steps

$ mkdir semver-test && cd semver-test
$ npm init

...

$ npm i semver
$ node
> const sv = require('semver')
> sv.satisfies('1.0.0-beta.1', '^1.0.0-beta.0 || ^0.16.0')
true

...

$ npm i redux-saga@"^1.0.0-beta.0 || ^0.16.0" --dry-run
+ redux-saga@0.16.0
added 1 package in 0.369s

$ npm i redux-saga@"^1.0.0-beta.0 || ^0.15.0" --dry-run
+ redux-saga@1.0.0-beta.1
added 5 packages in 0.675s

Details

Platform Info

$ npm --versions
{ 'semver-test': '1.0.0',
  npm: '5.6.0',
  ares: '1.10.1-DEV',
  cldr: '32.0',
  http_parser: '2.7.0',
  icu: '60.1',
  modules: '57',
  nghttp2: '1.25.0',
  node: '8.10.0',
  openssl: '1.0.2n',
  tz: '2017c',
  unicode: '10.0',
  uv: '1.19.1',
  v8: '6.2.414.50',
  zlib: '1.2.11' }
$ node -p process.platform
darwin

Then I updated to

$ npm --versions
{ 'semver-test': '1.0.0',
  npm: '6.4.0',
  ares: '1.10.1-DEV',
  cldr: '32.0',
  http_parser: '2.8.0',
  icu: '60.1',
  modules: '57',
  napi: '3',
  nghttp2: '1.32.0',
  node: '8.11.4',
  openssl: '1.0.2p',
  tz: '2017c',
  unicode: '10.0',
  uv: '1.19.1',
  v8: '6.2.414.54',
  zlib: '1.2.11' }

But nothing changed


This seems to be working pretty much as expected? Here’s what I think is happening:

In the first one, 0.16.0 is satisfied by the latest tag, so the algorithm finishes right off the bat – we prioritize the current tag (controlled by --tag) when finding the version we’re gonna use.

When you switch to using 0.15.0, neither of the two options in the range spec are latest, so the rest of the algorithm kicks in – and we find the semver.maxSatisfying() version. Thus, you end up with beta-1.

You can see the whole algorithm and walk through by hand by checking out npm-pick-manifest, which is what npm itself uses to make these decisions.

Cheers!