Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

In a monorepo with file links, npm install with lockfile fails to create some symlinks #750

Closed
jsnajdr opened this issue Jan 31, 2020 · 0 comments

Comments

@jsnajdr
Copy link
Contributor

jsnajdr commented Jan 31, 2020

Steps to reproduce

Create a monorepo-style project with the following structure:

/package.json

{
  "name": "monorepo",
  "dependencies": {
    "app": "file:./app"
  }
}

/app/package.json

{
  "name": "app",
  "dependencies": {
    "lib": "file:../lib"
  }
}

/lib/package.json

{
  "name": "lib"
}

There's a root package that depends on ./app which in turn depends on ../lib.

Now run npm install. That will produce a node_modules folder with two symlinks:

app -> ../app
lib -> ../lib

and a lockfile with this content:

{
  "name": "monorepo",
  "requires": true,
  "lockfileVersion": 1,
  "dependencies": {
    "app": {
      "version": "file:app",
      "requires": {
        "lib": "file:lib"
      }
    },
    "lib": {
      "version": "file:lib"
    }
  }
}

Notice an important fact: the dependencies.app.requires.lib field, with value file:lib, contains a path relative to the root of the tree. However, in package.json, the same dependency is specified relative to the requesting package's directory, i.e., file:../lib. We'll later see that this difference between package-lock.json and package.json formats is not correctly handled.

Now, with the lockfile present, delete the node_modules directory, and run npm install again. This time, it runs with no node_modules (i.e., empty currentTree), and installs from lockfile (unlike the first run)

Expected result:

The node_modules folder is the same as in the previous run, i.e., contains two symlinks to ../app and ../lib.

Actual result:

The node_modules folder contains only the app -> ../app symlink. The lib -> ../lib one is not present at all. npm install incorrectly determined that it's extraneous (not required by anyone) and prunes it (in pruneIdealTree)

See also:

To see a real-world example in a widely used project, just check out the lerna repo and run npm install there. Then, running npm ls reports a lot of missing package links:

npm ERR! missing: @lerna/cli@file:../../core/cli, required by @lerna-test/command-runner@0.0.0-test-only
npm ERR! missing: @lerna/package@file:../../core/package, required by @lerna-test/pkg-matchers@0.0.0-test-only
npm ERR! missing: @lerna/get-packed@file:../get-packed, required by @lerna/pack-directory@3.10.5
[...]
isaacs added a commit to npm/arborist that referenced this issue Feb 5, 2020
Fix: #43

This fixes the bug identified by npm/cli#750

Link deps that point to a location underneath the root package are fully
resolved and reified.  Links external to the root path are left alone,
because they exist in a different project and presumably have their own
dep resolution being done separately.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants