npm / cli

the package manager for JavaScript
https://docs.npmjs.com/cli/
Other
8.46k stars 3.15k forks source link

[BUG] npm install in workspace root installs optional peer dependencies of workspace package dependencies #2628

Open bradbarrow opened 3 years ago

bradbarrow commented 3 years ago

Current Behaviour:

See Steps to Reproduce for details.

When running npm install in the root of a project with workspaces configured, duplicate versions of react are installed because npm installs the version that one of my packages depends on directly AND a version of react that is an optional peer dependency of one of my package's dependencies resulting in:

react@16.14.0 is installed in /root/node_modules/react react@17.0.0 is installed in /root/apps/next-js-app/node_modules/react

Running the app with npm run dev results in React errors from duplicate versions of react

Expected Behavior:

react@17 satisfies my next app's own dependency AND the peer dependency of @apollo/client and thus only:

react@17.0.0 is installed in /root/node_modules/react

Steps To Reproduce:

I've provided the following reproduction example https://github.com/bradbarrow/npm-peer-deps-workspaces Run npm install in the root of that repository and note the duplicate versions of react with npm list react

OR follow the full reproduction steps below:

  1. Create a workspace root in /root with a workspace config "workspaces": ["apps/*"]
  2. Create a NextJS app in the apps/next-js-app directory
  3. Add react@17 to the package.json of the NextJS app
  4. Add react-dom@17 to the package.json of the NextJS app
  5. Add @apollo/client@3..3.7 to the package.json of the NextJS app
  6. Note that @apollo/client@3..3.7 has an optional peerDependency of "react": "^16.8.0 || ^17.0.0"
  7. Run npm install in the root of the project

Environment:

darcyclarke commented 3 years ago

@bradbarrow can you try to reproduce on the latest version of npm? (ie. npm i -g npm)

jamesbvaughan commented 2 years ago

I believe I'm seeing this same behavior with npm v8.9.0.

@bradbarrow Did you end up finding a workaround for this?

kleinfreund commented 6 months ago

Update: The below might be the expected result for a peer dependency stated with an exact version (e.g. 1.1.0 instead of ^1.1.0).

Original message I’m pretty sure I’m seeing this behavior with v10.5.2. I have `package-a@1.2.0` appear in my lock file as a direct dependency of `workspace-1`. A corresponding lock file entry for `node_modules/package-a@1.2.0` exists. `package-a` appears a few more times as a peer dependency on a generally different (older) version in _some_ of my workspaces’ dependencies (e.g. in `workspace-2`). For this version, additional lock file entries for `packages/workspace-2/node_modules/package-a@1.1.0` are created. As a consequence, in those workspaces, the module resolution finds the older version of `package-a` (`package-a@1.1.0`). In this case, the peer dependency isn’t missing; it’s already installed because a workspace package directly depends on it. Why is npm installing two versions of this package? Seeing that `npm dedupe package-a` doesn’t remove the duplicated entry, it looks like npm thinks the entry is required to satisfy workspace-2’s peer dependency.