NPM doesn't hoist linked module dependencies to project level when new dependencies are added to linked module


(Joe Pea) #1

What I Wanted to Do

Update the dependencies of a module that is linked into my project, and expect things to work.

What Happened Instead

Unless I also install the same dependency in the top-level project where I’ve linked the sub-module to, then the sub-module’s new dependency will not be picked up when running various tools (f.e. Webpack, Karma, etc).

So, I have this structure:

project
  node_modules
    linked-module

And I go into linked-module folder, npm install some-new-module, then when I return to project folder and run something (f.e. Webpack, Karma, and others), they complain that they can’t find some-new-module.

This happens quite often with npm link workflows and various build/test tools.

The workaround is that when I return to project folder, I run npm i some-new-module --no-save, so that the dependency exists, but without adding it to project's package.json.

Reproduction Steps

I don’t have a specific reproduction at the moment, but it happen often in various unrelated projects whenever I use npm link workflow a lot. I’m sure I’m not the only encountering it.

I will try to post a reproduction when I can.

Platform Info

$ npm --versions
{ npm: '6.5.0',
  modules: '57',
  node: '8.11.3', }

$ node -p process.platform
darwin

(Lars Willighagen) #2

This seems like appropriate behavior in the case of symlinked directories. A number of reasons npm install shouldn’t just hoist subdeps out of symlinked deps:

  • linked-module likely wouldn’t have access to it anymore, as the toplevel project node_modules probably isn’t “above” the original directory location
  • linked-module might be linked to multiple other places, hoisting some-new-module to a single one of those places wouldn’t make sense
  • if project needs some-new-module, why not install it and list it as a dependency?

However, in this case it seems like Webpack, Karma, and others don’t handle nested dependencies well? I’m not really sure what’s going wrong there…


(Joe Pea) #3

@larsgw Hello Lars, I believe I may have used the wrong word. What I meant by my version of “hoist” is "also install the linked module’s dependencies at the top level of the project.

So the result would be the same as if we had not linked the module, but had instead installed it as normal (which flattens all of the dependencies to the top level), then subsequently linked the module. This result in a symlink being created, and the dependencies now exist in two places: at the top level, and inside the linked module. In this case, all tooling seems to work well.

I suppose a plain Node.js program will be able to find nested dependencies if they are not at the top level? As in, if linked module uses a dependency, Node.js will look in that module’s node_modules first?

In the cases where I have issues with a linked module’s dependencies not being at the top level, it’s always with tooling like Webpack, Karma, etc.

Looks like there’s nothing to change here then, and that those projects need to implement module resolution more closing matching Node.js’s.