npm ci seems to install an optional dependency for the linux os when running on a mac and seems to install the optional dependency for mac when running on linux.
$ npm init -y; npm i [email protected]; npm ls; npm ci; npm ls
Wrote to /private/tmp/d/package.json: { "name": "d", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC" } > [email protected] postinstall /private/tmp/d/node_modules/oax > node ./postinstall.js npm notice created a lockfile as package-lock.json. You should commit this file. npm WARN [email protected] No description npm WARN [email protected] No repository field. npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules/oax/node_modules/oax-windows-64): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"win32","arch":"x64"} (current: {"os":"darwin","arch":"x64"}) npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules/oax/node_modules/oax-linux-64): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"linux","arch":"x64"} (current: {"os":"darwin","arch":"x64"}) + [email protected] added 2 packages and audited 4 packages in 1.1s found 0 vulnerabilities [email protected] /private/tmp/d └─┬ [email protected] ├── [email protected] ├── UNMET OPTIONAL DEPENDENCY [email protected] └── UNMET OPTIONAL DEPENDENCY [email protected] npm WARN prepare removing existing node_modules/ before installation > [email protected] postinstall /private/tmp/d/node_modules/oax > node ./postinstall.js added 3 packages in 0.722s [email protected] /private/tmp/d └─┬ [email protected] ├── [email protected] ├── [email protected] └── UNMET OPTIONAL DEPENDENCY [email protected]
currently it looks like npm ci is broken for optional dependencies which use the os and arch fields of package.json
$ npm init -y; npm i [email protected]; npm ls; npm ci; npm ls
You should see that npm i
works correctly and installs a single optional dependency for oax.
You should also see that npm ci
works incorrectly and installs two of the optional dependencies for oax, this should never happen as each optional dependency is targeting a different operating system and architecture, it should be impossible to have more than one of the optional dependencies installed.
it should install oax-darwin when running on darwin and should install oax-linux when running on linux
I ran into the same problem with fsevents on Windows, when installing two packages that depend on different versions of fsevents.
npm install chokidar --save
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
+ [email protected]
added 14 packages from 17 contributors and audited 19 packages in 1.668s
found 0 vulnerabilities
npm install webpack --save-dev
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules\watchpack\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
+ [email protected]
added 327 packages from 195 contributors and audited 4246 packages in 16.581s
Latest webpack depends on watchpack which depends on an older [email protected] which depends on an old [email protected].
While chokidar latest depends on [email protected]
But npm install skipped correctly both versions of fsevents as they are OS-incompatible.
However:
npm ci
npm WARN prepare removing existing node_modules/ before installation
> [email protected] install K:\SWS\test\node_modules\watchpack\node_modules\fsevents
> node-gyp rebuild
K:\SWS\test\node_modules\watchpack\node_modules\fsevents>if not defined npm_config_node_gyp (node "C:\Program Files\nodejs\node_modules\npm\node_modules\npm-lifecycle\node-gyp-bin\\..\..\node_modules\node-gyp\bin\node-gyp.js" rebuild ) else (node "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\bin\node-gyp.js" rebuild )
Traceback (most recent call last):
File "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\gyp\gyp_main.py", line 50, in <module>
sys.exit(gyp.script_main())
File "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\gyp\pylib\gyp\__init__.py", line 554, in script_main
return main(sys.argv[1:])
File "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\gyp\pylib\gyp\__init__.py", line 547, in main
return gyp_main(args)
File "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\gyp\pylib\gyp\__init__.py", line 532, in gyp_main
generator.GenerateOutput(flat_list, targets, data, params)
File "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\gyp\pylib\gyp\generator\msvs.py", line 2033, in GenerateOutput
root_entries = _GatherSolutionFolders(
File "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\gyp\pylib\gyp\generator\msvs.py", line 1791, in _GatherSolutionFolders
return _DictsToFolders('', root, flat)
File "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\gyp\pylib\gyp\generator\msvs.py", line 1744, in _DictsToFolders
for folder, contents in bucket.items():
AttributeError: 'MSVSProject' object has no attribute 'items'
gyp ERR! configure error
gyp ERR! stack Error: `gyp` failed with exit code: 1
gyp ERR! stack at ChildProcess.onCpExit (C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\lib\configure.js:351:16)
gyp ERR! stack at ChildProcess.emit (events.js:210:5)
gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:272:12)
gyp ERR! System Windows_NT 10.0.17134
gyp ERR! command "C:\\Program Files\\nodejs\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\npm\\node_modules\\node-gyp\\bin\\node-gyp.js" "rebuild"
gyp ERR! cwd K:\SWS\test\node_modules\watchpack\node_modules\fsevents
gyp ERR! node -v v12.14.0
gyp ERR! node-gyp -v v5.0.5
gyp ERR! not ok
added 275 packages in 9.344s
And if I look in node_modules, fsevents is there and it shouldn't be.
Also, npm ci --no-optional
doesn't work, this is reported here: https://github.com/npm/cli/issues/637
I'm using the Node 12 LTS install, npm -v
=> 6.13.4
Whether npm ci --no-optional
works may depend on additional factors. See https://github.com/npm/cli/issues/637#issuecomment-570813804
So while npm ci
fails in my environment, npm ci --no-optional
works. My environment:
After updating to latest node and npm have same issue.. all projects where it is fsevent fail to install with npm ci
, because it is building fsevents
After updating to latest node and npm have same issue.. all projects where it is fsevent fail to install with
npm ci
, because it is building fsevents* Windows 10 Pro 1909 * node 12.14.1 * npm 6.13.6
@padinko Did you also try the variant with the additional
--no-optional
flag, i.e.npm ci --no-optional
? Any difference?
After updating to latest node and npm have same issue.. all projects where it is fsevent fail to install with
npm ci
, because it is building fsevents* Windows 10 Pro 1909 * node 12.14.1 * npm 6.13.6
@padinko Did you also try the variant with the additional
--no-optional
flag, i.e.npm ci --no-optional
? Any difference?
npm ci
fail with this packages:
\node_modules\watchpack\node_modules\fsevents
\node_modules\webpack-dev-server\node_modules\fsevents
\node_modules\jest-haste-map\node_modules\fsevents
npm ci --no-optional
have only 2 of them:
\node_modules\webpack-dev-server\node_modules\fsevents
\node_modules\jest-haste-map\node_modules\fsevents
so there it is difference, but still compiling fsevents
@paulmillr @pipobscure My issue (#658) was a duplicate of this ticket. Track this one to stay up to date.
I can confirm this bug also on Ubuntu. npm ci
installs fsevents
that should be installed only on MacOS
@mikemimik or @isaacs, do you have any input on this bug? Yes, fsevents
changed something why this is now a bigger issue. But the underlying issue is still caused by NPM, and should be resolved here.
It looks like the relevant change is that fsevents started using node-pre-gyp to pull a precompiled binary, rather than building it in place, resulting in a postinstall
script that exits without an error on all platforms. Since npm ci
just tries to lay out whatever is in the lockfile without checking whether it supports the platform, and only removes optional deps whose install scripts fail, it results in installing this dep.
npm v7 won't have this problem. (I'm working in the code that'll do this now.) I haven't checked into how involved it'd be to fix this issue for npm v6, but there's a good chance it'll just end up being "upgrade to v7 for the fix". In the meantime, I'd recommend using npm install
instead of npm ci
if this is affecting you.
Yes, fsevents
changed their tactic. But it is actually the other way around. They used to have precompiled binaries. Installation on Windows would give a 404, and skip. Now it tries to build, and then breaks the build. Because the build shouldn't even get started. Regardless: npm ci
is designed for CI environments. How should we then use npm i
instead? We want the strict package-lock checks in CI.
Also: Would npm@7
land in Node 14, in time before it's LTS? Am I correct to assume we're stuck with npm i
or a version lock for a year when in the LTS track?
Sorry for changing tactics on you. However we lost access to the S3 originally used and it was becoming an increasingly serious security issue. That’s why we went back to build as needed. Especially given that v2.x based on NAPI doesn’t need to build at all for node v8.x+
Now it tries to build, and then breaks the build. Because the build shouldn't even get started.
Oh, that's weird. I'd expect npm ci
to handle a build failure from an optional dep as a non-fatal warning type event, and just remove the offending dep.
Regardless: npm ci is designed for CI environments. Why should we then use npm i instead? We want the strict package-lock checks in CI.
Good question.
"Designed for CI environments" does not always mean "best for this particular CI environment, for this particular application".
In this case, there are two issues that npm ci is running into.
So, you should use npm i
rather than npm ci
because it will work, avoiding both bugs.
We want the strict package-lock checks in CI.
If you're talking about the fact that the package-lock provides the authoritative integrity and resolution checks, then good news: npm install
does that as well.
If you're talking about the check that the package-lock and package.json are in sync with one another, you can add "scripts": { "prepare": "npx lock-verify" }
to your package.json.
Would npm@7 land in Node 14, in time before it's LTS?
That is my expectation, yes.
But, even if it is LTS, the approach in the past has been to have an LTS version of npm in the LTS version of node, even if that means it changes within the LTS "frozen" time frame, so shipping npm v6 for 4 years would be a profoundly bad idea that I don't think Node will do. And as npm is really something of a separate project, rather than a "dependency" in a way that affects the run-time, this is usually fine.
Since npm v7 will have some breaking changes (though we're trying to minimize these as much as possible), it may be an issue if we don't get it there in time, or we may make some concessions to set default configs or do other things so that the npm v7 that ships with node 14 LTS is as close as possible to npm v6.
Oh, I just checked the node lts schedule and see that I was mistaken about hte timeframe. Node 14's _initial_ release is in 3 months, but it doesn't go LTS until October.
So yeah, we should be well in the clear. I expect that the initial release of npm v7 will be available in time for node 14, and more than sufficiently stable by the time v14 hits LTS. (Famous last words and all, but the confidence has been steadily rising as we've gotten closer to doing the integration, and I don't have any reason to think that will change soon.)
I'm surprised this isn't being treated as more important of a bug that it is. This is making it so that we can't use "npm ci" on our build servers in windows. That's a big deal.
Not just windows, I can't use npm ci on any system
If you're talking about the fact that the package-lock provides the authoritative integrity and resolution checks, then good news:
npm install
does that as well.
Wait.. it's been my experience that npm install
will potentially result in updating the package-lock.json file if new packages are available that still adhere to the rules set in the package.json file.
Has this functionality changed @isaacs ?
@tommck I think he addresses that with this part:
If you're talking about the check that the package-lock and package.json are in sync with one another, you can add
"scripts": { "prepare": "npx lock-verify" }
to your package.json.
Guess you can use it as a poor man's implementation of npm ci
in your CI environment. You would run npm install
; this runs the prepare script that checks if the package-lock is still in sync with your package.json.
If I'm not mistaken, this has two problems:
So yeah, it's a big issue - luckily in our case we do builds on linux and they still work for our combination of packages... Other people are less lucky.
@coyoteecd So... assuming the lock file was fine (correct/verified), running "npm install" still might modify the package lock file with new dependencies?
running "npm install" still might modify the package lock file with new dependencies?
Incorrect. It will not do that.
Running npm install
with no arguments will not add any dependencies that differ from what's in the lockfile.
What npm install
will do, which npm ci
will _not_ do, is _skip_ downloading dependencies that are in node_modules
and already match what's in the lockfile.
Wait.. it's been my experience that npm install will potentially result in updating the package-lock.json file if new packages are available that still adhere to the rules set in the package.json file.
Has this functionality changed @isaacs ?
I'd love to see a case where that happens. Unless you're explicitly telling it not to respect the lockfile, or running npm update
, or the lockfile is invalid (ie, deps do not have their dependencies met by the tree it defines), the lockfile has locked down npm install
ever since it was introduced in npm v5.
full-icu
is package, which is sometimes changing lock file.. but i think it's their issue, not npm
my experiences: when you have node v12, and another developer have v10, full-icu downgrade icu data package for node v10..
when you have lock with everything and no node_modules
directory and run npm i
it will remove icu data from lock file, you need to run npm i
second time to add it again..
we was using npm ci, because of this 2 issues
For anyone else who ends up here due to fsevents
, this is the npm ci
solution from their corresponding issue:
https://github.com/fsevents/fsevents/issues/301#issuecomment-572607085
@jayoungers FWIW, that solution did not work for me. Somehow a different version of fsevents is still getting built with npm ci
. I had to change my build processes to use npm i
instead.
Are there any updates on this? We're also affected by this bug.
Not sure if this helps, but I ran into this issue when running npm install
in a package where package-lock.json
had already been generated in Linux (WSL in my case). After deleting package-lock.json
and re-running npm install
in Windows, I was fine.
Seems Serverless Pro CI changed from npm install to npm ci and this problem also occurs and breaks the build
I'm committing from a windows machine
build step: npm ci
> [email protected] postinstall /nuxt-serverless/node_modules/core-js
> node -e "try{require('./postinstall')}catch(e){}"
> [email protected] postinstall /nuxt-serverless/node_modules/ejs
> node ./postinstall.js
> [email protected] install /nuxt-serverless/node_modules/watchpack/node_modules/fsevents
> node-gyp rebuild
gyp
ERR! build error
gyp
ERR! stack Error: not found: make
gyp ERR! stack at getNotFoundError (/root/.nvm/versions/node/v10.13.0/lib/node_modules/npm/node_modules/which/which.js:13:12)
gyp
ERR! stack at F (/root/.nvm/versions/node/v10.13.0/lib/node_modules/npm/node_modules/which/which.js:68:19)
gyp ERR! stack
at E (/root/.nvm/versions/node/v10.13.0/lib/node_modules/npm/node_modules/which/which.js:80:29)
gyp ERR! stack at /root/.nvm/versions/node/v10.13.0/lib/node_modules/npm/node_modules/which/which.js:89:16
gyp ERR!
stack at /root/.nvm/versions/node/v10.13.0/lib/node_modules/npm/node_modules/isexe/index.js:42:5
gyp ERR! stack at /root/.nvm/versions/node/v10.13.0/lib/node_modules/npm/node_modules/isexe/mode.js:8:5
gyp
ERR! stack at FSReqWrap.oncomplete (fs.js:154:21)
gyp ERR!
System Linux 4.14.171-105.231.amzn1.x86_64
gyp ERR! command "/root/.nvm/versions/node/v10.13.0/bin/node" "/root/.nvm/versions/node/v10.13.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /nuxt-serverless/node_modules/watchpack/node_modules/fsevents
gyp ERR!
node -v v10.13.0
gyp ERR! node-gyp -v v3.8.0
gyp ERR! not ok
Using npm install --no-optional
does not work as a workaround.
moment is marked as optional in package-lock.json
:
"moment": {
"version": "2.29.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==",
"dev": true,
"optional": true
}
When I remove moment from node_modules npm i
will put it back:
rm -rf node_modules/moment
npm install --no-optional
ls node_modules | grep moment
moment
@Elijen I don't believe that is the same issue as this thread is about, which is OS targets for packages. You may want to file a separate issue if one does not already exist.
Oh, and by the way, fsevents
does not have this issue anymore since May 5th:
https://github.com/fsevents/fsevents/issues/301
@isaacs Did this land in npm@7
?
@paulirwin Maybe you are right. I saw multiple issues and forum posts created about the issue I mentioned and assumed this one is just a downstream issue caused by it.
I'd love to see a case where that happens. Unless you're explicitly telling it not to respect the lockfile, or running
npm update
, or the lockfile is invalid (ie, deps do not have their dependencies met by the tree it defines), the lockfile has locked downnpm install
ever since it was introduced in npm v5.
I've seen npm install
update dependencies with a valid lockfile on v6.14.8, when package versions are specified by tag. Logged as #2167.
The good news is that it doesn't appear to be happening in v7.0.10 :+1:
Most helpful comment
I'm surprised this isn't being treated as more important of a bug that it is. This is making it so that we can't use "npm ci" on our build servers in windows. That's a big deal.