npm / cli

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

[BUG] Platform-specific optional dependencies not being included in `package-lock.json` when reinstalling with `node_modules` present #4828

Open JustinChristensen opened 2 years ago

JustinChristensen commented 2 years ago

Is there an existing issue for this?

This issue exists in the latest npm version

Current Behavior

[user@host:foo] $ npm -v
8.8.0
[user@host:foo] $ node
Welcome to Node.js v16.14.2.
Type ".help" for more information.
> process.arch
'arm64'

I'm working on a team that utilizes a mix of x64-based and m1-based macs, and has CI build processes that uses musl. We're seeing that npm is skipping platform-specific optional dependencies for packages such as @swc/core as a result of the package-lock.json file being generated without all of them included. In our case, this then causes linting to throw an exception, because one of our eslint plugins depends on @swc, which depends on having the platform specific @swc package also installed.

There seems to be at least two stages of cause to this. Firstly, when installing @swc/core from a clean slate working directory npm generates a package-lock.json with all of the optional dependencies for @swc/core listed:

[user@host:foo] $ npm install @swc/core
[user@host:foo] $ grep 'node_modules/@swc/core-*' package-lock.json
    "node_modules/@swc/core": {
    "node_modules/@swc/core-android-arm-eabi": {
    "node_modules/@swc/core-android-arm64": {
    "node_modules/@swc/core-darwin-arm64": {
    "node_modules/@swc/core-darwin-x64": {
    "node_modules/@swc/core-freebsd-x64": {
    "node_modules/@swc/core-linux-arm-gnueabihf": {
    "node_modules/@swc/core-linux-arm64-gnu": {
    "node_modules/@swc/core-linux-arm64-musl": {
    "node_modules/@swc/core-linux-x64-gnu": {
    "node_modules/@swc/core-linux-x64-musl": {
    "node_modules/@swc/core-win32-arm64-msvc": {
    "node_modules/@swc/core-win32-ia32-msvc": {
    "node_modules/@swc/core-win32-x64-msvc": {

And it only installs the platform specific package:

[user@host:foo] $ ls -l node_modules/@swc/
total 0
drwxr-xr-x  22 user  staff  704 Apr 29 15:39 core
drwxr-xr-x   6 user  staff  192 Apr 29 15:39 core-darwin-arm64

If I then remove my package-lock.json, leave my node_modules directory as-is, and then reinstall, I get:

[user@host:foo] $ rm -rf package-lock.json
[user@host:foo] $ npm install
[user@host:foo] $ grep 'node_modules/@swc/core-*' package-lock.json
    "node_modules/@swc/core": {
    "node_modules/@swc/core-darwin-arm64": {

That is, it then generates a package-lock.json with only the platform-specific dependency that was installed on this machine, and not with the other optional dependencies that should also be listed.

If you delete both node_modules AND package-lock.json, and then re-run npm install, it generates the correct lockfile with all of those optional dependencies listed.

The problem is that then, If the package-lock.json with the missing optional platform-specific dependencies gets checked into git and an x64 user pulls it down, or vice-versa, npm fails to detect that your platform's optional dependencies are missing in the lockfile and just silently skips installing the platform-specific dependency. For example, when I've got a package-lock.json that only contains the x64 @swc package because of the above problem (generated by my coworker on his x64 machine):

[user@host:foo] $ node
Welcome to Node.js v16.14.2.
Type ".help" for more information.
> process.arch
'arm64'
>
[user@host:foo] $ grep 'node_modules/@swc/core-*' package-lock.json
    "node_modules/@swc/core": {
    "node_modules/@swc/core-darwin-x64": {
[user@host:foo] $ ls
package-lock.json package.json

And I then install:

[user@host:foo] $ npm install
added 1 package in 341ms

1 package is looking for funding
  run `npm fund` for details
[user@host:foo] $ ls node_modules/@swc/
core

You can see that it fails to install the arm64 dependency or warn me in any way that the package-lock.json is missing my platform's dependency.

So yeah, two problems:

  1. npm is generating an inconsistent package-lock.json when node_modules has your platform-specific dependency installed.
  2. When installing from this inconsistent package-lock.json, npm fails to try to correct the problem by comparing the optional dependencies to what's listed upstream

Expected Behavior

  1. npm should preserve the full set of platform-specific optional deps for a package like @swc when rebuilding package-lock.json from an existing node_modules tree
  2. npm install should warn if the package-lock.json becomes inconsistent because of the first case

Steps To Reproduce

See above.

Environment

[user@host:foo] $ npm -v
8.8.0
[user@host:foo] $ node -v
v16.14.2
[user@host:foo] $ uname -a
Darwin host.foo.com. 21.3.0 Darwin Kernel Version 21.3.0: Wed Jan  5 21:37:58 PST 2022; root:xnu-8019.80.24~20/RELEASE_ARM64_T8101 arm64
[user@host] $ npm config ls
; "user" config from /Users/user/.npmrc
; node bin location = /Users/user/.nvm/versions/node/v16.14.2/bin/node
; node version = v16.14.2
; npm local prefix = /Users/user/Development/foo
; npm version = 8.8.0
; cwd = /Users/user/Development/foo
; HOME = /Users/user
; Run `npm config ls -l` to show all defaults.
JustinChristensen commented 2 years ago

@nlf

Sorry to ping you out of the blue, but this issue has been open for 11 days now without any movement. Is there anyone working on npm right now that might have the bandwidth to at least validate that this is indeed a problem as I've described it?

Just so that when someone does become available to do some development work they know that this is in the queue?

Please and thank you.

JustinChristensen commented 2 years ago

Bump

RobbieClarken commented 2 years ago

I'm also encountering this issue with a Next.js project:

Unfortunately developers often don't realise the package-lock.json file is broken because everything continues to run fine on their machine. It is only when the build runs in CI that we learn it is broken.

Here is a reproduction:

$ node --version
v16.13.0
$ npm --version
8.12.1
$ npx create-next-app@latest
What is your project named? … my-app
Creating a new Next.js app in /Users/robbie/demo/my-app.
$ cd my-app/
$ npm install

up to date, audited 223 packages in 480ms

68 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
$ git status
On branch main
nothing to commit, working tree clean
$ rm package-lock.json
$ npm install

up to date, audited 223 packages in 579ms

68 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
$ # ************ package-lock.json is now incompatible with x86 ************
$ git diff
diff --git a/package-lock.json b/package-lock.json
index cbbf946..a87c1e5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -96,36 +96,6 @@
         "glob": "7.1.7"
       }
     },
-    "node_modules/@next/swc-android-arm-eabi": {
-      "version": "12.1.6",
-      "resolved": "https://registry.npmjs.org/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-12.1.6.tgz",
-      "integrity": "sha512-BxBr3QAAAXWgk/K7EedvzxJr2dE014mghBSA9iOEAv0bMgF+MRq4PoASjuHi15M2zfowpcRG8XQhMFtxftCleQ==",
-      "cpu": [
-        "arm"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/@next/swc-android-arm64": {
-      "version": "12.1.6",
-      "resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-12.1.6.tgz",
-      "integrity": "sha512-EboEk3ROYY7U6WA2RrMt/cXXMokUTXXfnxe2+CU+DOahvbrO8QSWhlBl9I9ZbFzJx28AGB9Yo3oQHCvph/4Lew==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">= 10"
-      }
-    },
[...]
$ rm -r package-lock.json node_modules
$ npm install

added 222 packages, and audited 223 packages in 2s

68 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
$ # ************ package-lock.json is now ok again ************
$ git status
On branch main
nothing to commit, working tree clean
pete55104 commented 2 years ago

I am also having this issue. I'm trying to run tests using jest with swc. The test runner is a linux image, but my dev machine is darwin. I can get it to work by either using --force to install the linux dependency, or I can install packages from inside the container... but github CI stands up the docker container in such a way that I can't easily install packages from in there, and that also prevents me from maintaining a cached node modules etc.

johnculviner commented 2 years ago

bump

nikkhn commented 2 years ago

bump - cannot get optional dependencies (namely @swc/core-linux-arm64-gnu) to install on my linux distro

sgoodluck commented 2 years ago

bump

alcuadrado commented 2 years ago

Confirming that this issue is still present. It's particularly important for projects using NAPI modules, as tons of them use platform-specific packages.

AboldUSER commented 2 years ago

Ran into this issue when creating a CI process for a repo where I use a Windows machine and the CI process is using Linux. My quick "fix" for now is to start the CI process by deleting the package-lock.json and running npm install instead of npm ci. I know this is not good practice, so looking forward to a real fix to come through.

eliotSmithNYC commented 2 years ago

bump

douglassllc commented 1 year ago

I am having a similar issue. My project uses @ffmpeg-installer/ffmpeg. While using npm v6 all optional dependencies (arch specific) are installed. After my upgrade to npm v8 the optional dependencies no longer install. Per the npm documentation I attempted using --include=optional, but this did not resolve the issue.

What has changed between v6 and v8 and is there an npm config option that will have v8 work similar to v6 when it comes to optional dependencies?

ljharb commented 1 year ago

@douglassllc following https://unpkg.com/browse/@ffmpeg-installer/ffmpeg@1.1.0/package.json to eg https://unpkg.com/browse/@ffmpeg-installer/darwin-arm64@4.1.5/package.json, that package should only be installed when the "os" is darwin and the "cpu" is arm64. If you're on a machine that doesn't match those, it wouldn't be installed.

douglassllc commented 1 year ago

@ljharb thanks for the quick reply.

While using npm v6 I could run npm install --force and all archs for @ffmpeg-installer/ffmpeg would be installed. I know this was not the intention of this package, but it was nice that I could force another behavior. This is advantageous for my scenario as I am building an Electron app that supports multiple OSs / Archs. Once I upgraded to npm v8 the --force is no longer pulling down / installing all the available optional dependencies for this package. This means no way for me to build on Mac for Windows as the Windows ffmpeg executables are not being downloaded.

Reading the npm documentation, it seemed the --include=optional might allow me to forcefully pull down all the optional dependencies in @ffmpeg-installer/ffmpeg. However, this is not working I would expect.

I read through all the npm config options, but did not see anything other than --include which might allow for npm v8 to work similar to npm v6. Any recommendations or suggestions would be appreciated.

woody-li commented 1 year ago

What has changed between v6 and v8 and is there an npm config option that will have v8 work similar to v6 when it comes to optional dependencies?

This issue also reproduced at v7.

grusingh commented 1 year ago

Does pnpm addresses this issue?

stephanrotolante commented 1 year ago

NPM Version 8.11.0

npm ci --omit=optional is still including pkgs that are not supported by my architecture even though I explicitly set the dependency and all versions of it as optional

silverwind commented 1 year ago

Also reproduces on npm@9.6.1.

alcuadrado commented 1 year ago

Commenting again here hoping to help the team prioritize this issue.

  1. With the proliferation of NAPI-based native modules, in particular for development tools (e.g. esbuild), many projects are using platform-specific optional packages, either directly or as (transitive) dependencies.

  2. This issue makes those projects very fragile, as deleting the lockfile and reinstalling is a common practice, and triggers this bug.

  3. Moreover, the developer that does it won't notice any problem, until (hopefully) their cross-platform CI fails, or one of their teammates' workflow breaks.

Ketcap commented 1 year ago

Having this issue,

cdimino commented 1 year ago

I was able to get past this by manually editing my package-lock.json file to include the extra platform dependencies from another project that wasn't broken.

Naija-geek commented 1 year ago

delete the node_modules rm -rf node_modules

delete the package-lock.json or yarn.lock rm -f package-lock.json rm -f yarn.lock

clean the npm cache npm cache clean --force

Install the dependencies npm install

b12k commented 1 year ago

This issue (maybe) is caused by regeneration of package-lock.json when node_modules are already present.

The rule of thumb:

⚠️ If you want to regenerate package-lock.json (for any reason) remove node_modules before running npm install.

This bug/feature is not reproducible when using Yarn/PNPM and respective yarn.lock/pnpm-lock.yaml lock files

Example:

# Initial step
npm init -y
npm i turbo
# 👌 package-lock.json is generated 
# Case A
rm -rf package-lock.json
npm i
# package-lock.json is regenerated taking `node_modules` into consideration
# SO
# ❌ Initial step package-lock.json != Case A package-lock.json
# Case B
rm -rf package-lock.json node_modules
npm i
# package-lock.json is regenerated using only package.json
# SO
# ✅ Initial step package-lock.json == Case B package-lock.json

image

henryjjjjj commented 1 year ago

delete the node_modules rm -rf node_modules

delete the package-lock.json or yarn.lock rm -f package-lock.json rm -f yarn.lock

clean the npm cache npm cache clean --force

Install the dependencies npm install

Thank you, cleaning the cache worked! Azure CI is now building again!

sanjaymereddy commented 1 year ago

https://github.com/nrwl/nx-console/issues/1808 I still have this issue. I get below errors on my windows machine when I installed the "Nx Console" extension. I verified that I'm using VS Code and node 64bit. As @devongovett mentioned, package manager fails to install the dependencies correctly

error

localpcguy commented 1 year ago

This issue (maybe) is caused by regeneration of package-lock.json when node_modules are already present.

This definitely seems to be the issue, particularly (in my case at least) with respect to optional packages. When I run npm install without any node_modules, it installs the appropriate version for my system/os, but the package-lock still references all of the optional packages. But if I regenerate the package-lock after node_modules exist, it will only reference the installed optional dependencies in the package-lock and removes any that weren't installed for my system/os combo.

This become a problem then on CI, where the system/os is different and so it needs a different one of the optional dependencies, but won't install it because it is no longer referenced at all in the package-lock json file. My expectation would be that while there might be slight version differences, the package-lock should not diverge in this manner due to the existence of node_modules during build.

There are a number of workarounds that work, but it can be a bit of a pain to manage this discrepancy. As the package-lock file is generated, I would also not expect I need to manually manage merge conflict resolution, but that I can just regenerate it as needed, but this issue means that doesn't always work properly.

lmgeorge commented 1 year ago

delete the node_modules rm -rf node_modules

delete the package-lock.json or yarn.lock rm -f package-lock.json rm -f yarn.lock

clean the npm cache npm cache clean --force

Install the dependencies npm install

For now, we've added this workaround as part of the project's package.json. It's not elegant, but it works.

{
  "scripts": {
    "prereinstall": "rm -rf ${npm_config_cache} ./package-lock.json ./npm-shrinkwrap.json ./node_modules",
    "reinstall": "npm_config_package_lock=true npm i",
    "postreinstall": "npm shrinkwrap" // optional
  }
}
sametsahin1 commented 1 year ago

Ekran görüntüsü 2023-11-28 201047 I'm getting the same error. After deleting 2 files and cleaning the cache, I uploaded it 20 more times, but I'm getting the same error.

Diboby commented 1 year ago

Did you try with ‘-f’ option ?

sametsahin1 commented 1 year ago

Ekran görüntüsü 2023-11-28 203452 Now I tried again with force and got the same error again.

Diboby commented 1 year ago

Add @rollup/rollup-win32-x64-msvc in your dev dependencies with 'npm i -f -D @rollup/rollup-win32-x64-msvc'

sametsahin1 commented 1 year ago

unfortunately I keep getting the same error

MuhammadAshraf23 commented 12 months ago

Add @rollup/rollup-win32-x64-msvc in your dev dependencies with 'npm i -f -D @rollup/rollup-win32-x64-msvc'

not solve ,after npm i -f -D @rollup/rollup-win32-x64-msvc

MuhammadAshraf23 commented 12 months ago

Ekran görüntüsü 2023-11-28 203452 Now I tried again with force and got the same error again.

Hey bro, is the issue solved?

mrdulin commented 12 months ago
C:\Users\Lin Du\Desktop\workspace\mrdulin\KLineChart\node_modules\vite\node_modules\rollup\dist\native.js:64
                throw new Error(
                      ^

Error: Cannot find module @rollup/rollup-win32-x64-msvc. npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). Please try `npm i` again after removing both package-lock.json and node_modules directory.
    at requireWithFriendlyError (C:\Users\Lin Du\Desktop\workspace\mrdulin\KLineChart\node_modules\vite\node_modules\rollup\dist\native.js:64:9)
    at Object.<anonymous> (C:\Users\Lin Du\Desktop\workspace\mrdulin\KLineChart\node_modules\vite\node_modules\rollup\dist\native.js:73:48)
    ... 2 lines matching cause stack trace ...
    at Module.load (node:internal/modules/cjs/loader:1197:32)
    at Module._load (node:internal/modules/cjs/loader:1013:12)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:202:29)
    at ModuleJob.run (node:internal/modules/esm/module_job:195:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:336:24) {
  [cause]: Error: The specified module could not be found.
  \\?\C:\Users\Lin Du\Desktop\workspace\mrdulin\KLineChart\node_modules\@rollup\rollup-win32-x64-msvc\rollup.win32-x64-msvc.node
      at Module._extensions..node (node:internal/modules/cjs/loader:1452:18)
      at Module.load (node:internal/modules/cjs/loader:1197:32)
      at Module._load (node:internal/modules/cjs/loader:1013:12)
      at Module.require (node:internal/modules/cjs/loader:1225:19)
      at require (node:internal/modules/helpers:177:18)
      at requireWithFriendlyError (C:\Users\Lin Du\Desktop\workspace\mrdulin\KLineChart\node_modules\vite\node_modules\rollup\dist\native.js:62:10)
      at Object.<anonymous> (C:\Users\Lin Du\Desktop\workspace\mrdulin\KLineChart\node_modules\vite\node_modules\rollup\dist\native.js:73:48)
      at Module._compile (node:internal/modules/cjs/loader:1356:14)
      at Module._extensions..js (node:internal/modules/cjs/loader:1414:10)
      at Module.load (node:internal/modules/cjs/loader:1197:32) {
    code: 'ERR_DLOPEN_FAILED'
  }
}

Node.js v18.19.0

npm version: 10.2.3, 8.19.4

tanyamehra085 commented 12 months ago

Screenshot (52) Any solution for this

sametsahin1 commented 12 months ago

I deleted Windows 11 and reinstalled Windows 10 and downloaded vsc and continued without any problems. I never had this problem. My advice to friends who cannot solve it is never use Windows 11.

tanyamehra085 commented 12 months ago

any solution for this how to resolve this issue

alcuadrado commented 12 months ago

Please do not use this issue to report or discuss problems with tools other than npm. Try the general workaround of deleting your node_modules and package-lock.json and reinstall your project. But please, don't pollute this issue.

This is a real problem with npm, and adding noise here can decrease its visibility.

yuzakki commented 12 months ago

guys any solution for this, I have been tryna fix it for around 4h and getting the same error again and again.. I even deleted the current nodejs version on my system and reinstalled the latest version of it v21.3.0.

Annotation 2023-12-01 151857

tanyamehra085 commented 12 months ago

When creating the project, use "npm create vite@4.4.0" or "npm create vite@4.0.0 " instead of "npm create vite@latest" to ensure it works.

arifhossenbd commented 12 months ago

When creating the project, use "npm create vite@4.4.0" or "npm create vite@4.0.0 " instead of "npm create vite@latest" to ensure it works. I have same issue and tried this command but its not worked

abid365 commented 12 months ago

Ekran görüntüsü 2023-11-28 201047 I'm getting the same error. After deleting 2 files and cleaning the cache, I uploaded it 20 more times, but I'm getting the same error.

, Im also facing the exact same issue, my default user device is linux but when I cloned a certain project to run on windows it crashes, and shows the same error

tanyamehra085 commented 12 months ago

Ekran görüntüsü 2023-11-28 201047 I'm getting the same error. After deleting 2 files and cleaning the cache, I uploaded it 20 more times, but I'm getting the same error.

, Im also facing the exact same issue, my default user device is linux but when I cloned a certain project to run on windows it crashes, and shows the same error

When creating the project, use "npm create vite@4.4.0" or "npm create vite@4.0.0 " instead of "npm create vite@latest" to ensure it works.

have you tried this ?

eb110 commented 12 months ago

"npm create vite@4.4.0" or "npm create vite@4.0.0 " solved the issue

raykyri commented 12 months ago

Solved in my case by adding "@rollup/rollup-linux-x64-gnu": "4.6.1" to optionalDependencies at the top level.

Ydobro commented 11 months ago

Solved in my case by adding "@rollup/rollup-linux-x64-gnu": "4.6.1" to optionalDependencies at the top level.

Thank you!

npm i @rollup/rollup-linux-x64-gnu --save-optional

Solved the issue for me

DercilioFontes commented 11 months ago

npm i --package-lock=false worked for me.

package-lock Default: true Type: Boolean If set to false, then ignore package-lock.json files when installing. This will also prevent writing package-lock.json if save is true.

mammad2c commented 11 months ago

This solution worked for me:

First, try to find the package that produces the error, then install it as an optional dependency.

Here are the steps for me that worked:

At first, I was getting this error:

Error: Cannot find module @rollup/rollup-linux-arm64-musl. npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). Please try `npm i` again after removing both package-lock.json and node_modules directory.

I grabbed the package name from the error, here for me is @rollup/rollup-linux-arm64-musl And I ran the following command:

npm i @rollup/rollup-linux-arm64-musl --save-optional

auroraanna commented 11 months ago

you're not actually fixing the problem. those packages, you have to manually install. those packages are specific to each platform.

lovell commented 11 months ago

I've recently updated the cross-platform section of the sharp documentation to direct npm users to this issue as I'm seeing multiple reports and it is increasingly common. If you are affected by this problem, please add your :+1: to the top comment to help with visibility. This issue is currently the 2nd most upvoted open bug in npm.