npm / cli

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

[BUG] `npm ci` erroneously installs optional OS-constrained transitive dependency through direct shrinkwrap dependency #7622

Open restjohn opened 2 months ago

restjohn commented 2 months ago

Is there an existing issue for this?

This issue exists in the latest npm version

Current Behavior

Consider a package, lib1, with the following characteristics.

Developer A creates another package, app1, which depends on lib1, and generates app1's package-lock.json with npm install also on the platform matching said OS constraint.

Developer B, OR a CI process, on a different platform from said OS constraint, runs npm ci to install app1's dependencies. npm ci produces an error like the following.

[.../app1> npm ci
npm error code EBADPLATFORM
npm error notsup Unsupported platform for fsevents@2.3.3: wanted {"os":"darwin"} (current: {"os":"linux"})
npm error notsup Valid os:  darwin
npm error notsup Actual os: linux
npm error A complete log of this run can be found in: /root/.npm/_logs/2024-07-02T12_41_06_204Z-debug-0.log

Examining app1's package-lock.json reveals that npm does not include an "optional": true entry in the package-lock block for lib1's fsevents dependency.

Expected Behavior

npm ci should retain the optional nature of the platform-specific dependency and proceed with a successful clean install of app1's dependencies regardless of the dependencies.

Steps To Reproduce

  1. On a linux platform, clone the demo repository: https://github.com/restjohn/issues.npm.shrinkwrap_optional_dep.
  2. Use npm 10.8.1, latest at the time of this writing.
  3. cd app1
  4. npm ci
  5. npm should produce an error as in the Current Behavior section above.

Please see the README in the demo repository for quite a bit more detail about the nuances of this behavior.

Also note that the demo repository package lib1.shrinkwrap references the fsevents package through a devDependency, and npm should not be attempting to install lib1.shrinkwrap devDependencies from the app1 package anyway.

Environment

restjohn commented 2 months ago

Aside from the problem of forcing installation of an optional dependency, another cause of this bug is that npm is installing the dev dependencies from the shrinkwrapped package. Apparently this is quite a long-standing issue.

restjohn commented 1 month ago

Others are having issues with shrinkwrap as well: https://github.com/npm/cli/issues/4323.