Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Having project_name/node_modules as a symlink?

Related: single node_modules folder for multiple projects

If npm install -g everything is not recommended, and I do not want to link individual modules, can I possibly symlink <some project>/node_modules to a common directory to be shared by multiple projects?

like image 675
prusswan Avatar asked Mar 13 '23 19:03

prusswan


1 Answers

Node can handle the symlinks perfectly fine. How to achieve this is going to depend on some of your objectives. The most important being: what experience do you want to have for other developers who download your project(s) from version control?

When designing this experience, it is super helpful to read about the Node module loading algorithm, to get insight on what is possible.

  • Official documentation

  • Explanation of require() internals

In general, my recommendation is to not be concerned with duplicated dependencies between projects. "Fixing" this is not worth the maintenance cost, which includes dependency gridlock (conflicting needs of the subprojects) and needing custom tooling in some cases to account for your custom structure.

With that warning out of the way, how do we do it? The simplest way is to create a superproject that encapsulates various subprojects. The subprojects will effectively inherit the dependencies of the superproject.

superproject/
|-- node_modules/
|   +-- socket.io/
|-- package.json
|-- subprojectA/
|   |-- node_modules/
|   |   +-- browserify/
|   |-- package.json
|   +-- app/
|       +-- client.js
+-- subprojectB/
    |-- node_modules/
    |   +-- express/
    |-- package.json
    +-- lib/
        +-- server.js

This structure works how you might expect, the files within the subprojects can require() their own modules and any of those in superproject/node_modules, but they will not easily require() the modules within their sibling subprojects (it is still possible to do so via explicit paths). In other words, client.js can require() browserify and socket.io without a path, but it would need to use a path to require() express.

An important aspect of this is that npm does a "find up" search for a package.json and deals with modules in a node_modules directory as a sibling to that file when installing, etc. This means that your current working directory needs to be superproject in order to install modules in it, unless your subproject does not have a package.json file.

like image 134
Seth Holladay Avatar answered Mar 30 '23 01:03

Seth Holladay