cli icon indicating copy to clipboard operation
cli copied to clipboard

[BUG] `npm ci` does not remove/recreate existing `node_modules` inside workspaces

Open thislooksfun opened this issue 1 year ago • 3 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

This issue exists in the latest npm version

  • [X] I am using the latest npm

Current Behavior

Running npm ci behaves unintuitively in workspaces. When run in a project without workspaces, the behavior is straightforwards and clear:

  1. Validate that the package-lock.json is in sync
  2. Remove ./node_modules if it exists
  3. Install from package-lock.json

This makes perfect sense, and aligns with the documentation. However, when you run npm ci in a project with workspaces, it runs the same three steps. This sounds like it's fine, except that there is one key problem with step 2: it only deletes the root node_modules folder. Any node_modules in workspaces folders are left behind. This leads to a confusing inconsistency in the behavior of the npm ci command: on first install (if there are no node_modules installed at all), it will install the full tree, including workspaces. However, when running it a second time, it only cleanly reinstalls the root packages.

Expected Behavior

I would expect that npm ci would remove all the node_modules folders referenced in package-lock.json before trying to install again.

Steps To Reproduce

Here is a set of commands that illustrate the issue. If you run this script you will see that the hoisted abbrev installation gets properly reinstalled (removing foo.txt), but the inner one does not.

npm init -y
npm init -y -w workspace-a
npm init -y -w workspace-b

npm i --save-exact [email protected] -w workspace-a
npm i --save-exact [email protected] -w workspace-b

touch node_modules/abbrev/foo.txt
touch workspace-b/node_modules/abbrev/bar.txt

npm ci

# This will _not_ include foo.txt, as it has been deleted.
ls node_modules/abbrev
# This _will_ include bar.txt, as it has _not_ been deleted.
ls workspace-b/node_modules/abbrev

Environment

  • npm: 10.4.0 and 9.8.1
  • Node.js: v18.18.0
  • OS Name: macOS
  • System Model Name: Macbook Pro
  • npm config:
save-exact = true 
save-prefix = ""

thislooksfun avatar Feb 16 '24 21:02 thislooksfun

This is a possible duplicate of #4846, but that one was a slightly different situation (specifying a workspace to reinstall, rather than running npm ci bare), and also was closed almost 2 years ago, so I figured it would be better to open this as a new issue.

thislooksfun avatar Feb 16 '24 21:02 thislooksfun

Hi, I would like to contribute.

kalil0321 avatar Apr 14 '24 12:04 kalil0321

The ci stands for "clean install" - the behavior should live up to the name. If someone needs similar behavior to work cross-platform, you can use rimraf --glob ./**/node_modules.

DesignByOnyx avatar May 02 '24 04:05 DesignByOnyx