packages with peerDependencies are incorrectly hoisted

cli
triaged
priority:medium
(Tobias Koppers) #1

What I Wanted to Do

Install a package C, with two dependencies A and B, where A has a peerDependency on B, in into a project which has already another version of B hoisted to root node_modules, but no version of A.

Package A should be able to access the correct version of B via require(). It should not get the other hoisted version of B.

In the real case C = webpack, A = acorn-dynamic-import, B = acorn. acorn-dynamic-import contains a require("acorn").

What Happened Instead

npm hoisted package A to root node_modules, where the wrong version of package B is.

Example: C has A@2 and B@2. The project already contains B@1.

This results in this directory structure:

node_modules
  C
    node_modules
      B@2
  A@2
  B@1

In this structure any require("B") in package A results in the wrong module loaded.

Reproduction Steps

Here is a minimal example with https://github.com/sokra/npm-bug-peer-dependencies

Run: npm i

Note that I used file: dependency for a smaller example, but the problem is not related to it. You can replace file:package with "webpack": "4.29.0" to get the same results, but it installs more stuff.

Expected structure:

node_modules
  package
    node_modules
      acorn
      acorn-dynamic-import
  acorn

Actual structure:

node_modules
  package
    node_modules
      acorn
  acorn-dynamic-import
  acorn

Details

Yarn behaves correctly.

see also https://github.com/webpack/webpack/issues/8656

Platform Info

$ npm --versions
{ npm: '6.5.0',
  ares: '1.15.0',
  brotli: '1.0.7',
  cldr: '34.0',
  http_parser: '2.8.0',
  icu: '63.1',
  llhttp: '1.0.1',
  modules: '67',
  napi: '3',
  nghttp2: '1.34.0',
  node: '11.7.0',
  openssl: '1.1.0j',
  tz: '2018e',
  unicode: '11.0',
  uv: '1.24.1',
  v8: '7.0.276.38-node.16',
  zlib: '1.2.11' }
$ node -p process.platform
win32
0 Likes

unmet peerDependency (but it's listed as a dependency)
npm 6.8.0-next.0 regression in maximally flat install
Release: npm@6.8.0-next.2
Release: npm@6.8.0-next.0
(Kat Marchán) #2

This is a known issue and, unfortunately, something we won’t be able to fix until we get through an upcoming tree builder rewrite. peerDeps require a bit of extra attention to get right, and the current installer architecture can’t support this (this has been a known bug since npm@3!)

0 Likes

(Toru Nagashima) #3

Link to a same issue: Failed to install eslint in a specific situation

0 Likes

(Tobias Koppers) #4

I tried to fix this bug myself: https://github.com/npm/cli/pull/147

3 Likes

(Kat Marchán) #5

Thank you! We’ll get you a review soon and make sure this doesn’t run into any other weird corner cases or anything. I appreciate you taking the time to do this. :pray:

0 Likes

(Tobias Koppers) #6

This has been fixed.

EDIT: Fix has be reverted: https://github.com/npm/cli/pull/152

2 Likes

(Matt Travi) #7

this has been on my list of things to raise for quite a while, but haven’t followed through. thank you so much for pushing a fix through :tada:

1 Like

(Dimitri Kopriwa) #8

Is the fix released here? We are experiencing hard issue on all our documentation, see:




0 Likes

(Worc) #9

@kopax the fix was reverted

0 Likes