1

I have a git repo which contains a few Node.js powered websites; for simplicity of dependency management, all required production npm modules are committed to the repo. To save space and avoid duplication, I'd like to save many of the shared modules in a parent node_modules directory that each site (sub directory) can implicitly or explicitly use.

Example:

+
|- Site1
|  |- node_modules (modules unique to Site1, e.g. module1...)
|
|- Site2
|  |- node_modules (modules unique to Site2, e.g. module2...)
|
|- Site3
|  |- node_modules (modules unique to Site3, e.g. module3...)
|
|- node_modules (shared/common modules)
   |- shared1@2
   |- shared2@4
   |- etc.

The package.json file in each directory (Site1, Site2, Site3) references only the modules installed within that directory (not the shared ones that are used).

Imagine module1 used by Site 1 requires shared1@1, while the shared version is shared1@2.

With npm@1 and npm@2, this works fine as the dependencies for module1 are installed in its own node_modules subdirectory (Site1\node_modules\module1\node_modules\...).

With npm@3 and the flat hierarchy, we start to run into some problems. shared1@1 is installed to Site1\node_modules\shared1, and as a result Site1 will use that version instead of the 'correct' shared copy at node_modules\shared1.

What are the options for addressing this? I'm not sure npm link is viable, since it links via the local global directory (which isn't committed to git). Or should I give up, and just duplicate the modules in each sub-directory?

2 Answers 2

1

I found a workaround that seems to do what I want. Basically, for any module which is installed in the common node_modules directory, it is also listed in the site-specific sub-directory's package.json as a dependency. However, I don't actually install the package to the subdirectory.

The presence of the package in the sub-directory's manifest is sufficient for npm to avoid installing that package, or alternate versions of that package, in the root of the sub-directory's node_modules.

There are some limitations, such as tools (e.g. npm-check) thinking dependencies are missing, and not being able to do a full npm i in the sub-directory, but they're all easy to overcome. Hopefully this helps someone else in the same boat!

0
0

I found a way around it. Though it may not be exactly what you're looking for but apparently there is a "--legacy-bundling" flag you can use when running npm install which will install dependencies with nested sub dependencies.

so if you run:

npm install --legacy-bundling

For each site then it will work as you want it. This is the only way I can think of, though I know your goal was to de-duplicate your dependencies and this might accidentally cause more dependency duplication than just having all dependencies in each site's package.json.

1
  • Thanks; falling back to the nested behavior is certainly an option I can consider, though I'd prefer to take advantage of the flat modules if possible.
    – Dan
    Commented May 11, 2017 at 0:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.