Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does every git branch of an NPM project have different node_modules dependencies?

Tags:

git

node.js

npm

I assume that when developing an NPM project, that every git branch (or whatever version control system you use) probably points to a different set of node_modules on the filesystem. Is that true? How does that work? Does it pose any problems for diskspace etc?

Or perhaps, since node_modules is most commonly .gitignore'd, then the node_modules files are shared between Git branches? Again, how would/does that work?

*Note that Node.js / NPM is fundamentally different than other platforms/languages since dependencies are typically stored locally to a proejct rather than in some central location on a machine.

like image 385
Alexander Mills Avatar asked Oct 21 '16 00:10

Alexander Mills


People also ask

Should you include node_modules in git?

For reference, npm FAQ answers your question clearly: Check node_modules into git for things you deploy, such as websites and apps. Do not check node_modules into git for libraries and modules intended to be reused. Use npm to manage dependencies in your dev environment, but not in your deployment scripts.

Where are global node_modules stored?

Path of Global Packages in the system: Global modules are installed in the standard system in root location in system directory /usr/local/lib/node_modules project directory. Command to print the location on your system where all the global modules are installed.

Do I need to install node modules for every project?

Global installing dependencies puts the module into your Node. js path, which is Operating System dependent) and will be accessible from any project without the need to install it separately for each project while doing the setup.

Will npm install install all dependencies?

By default, npm install will install all modules listed as dependencies in package.


2 Answers

By convention, one should not add any files, libraries or binaries which can be generated or pulled in from an external source. This includes things like node_modules; since that is made readily available* once you do npm install, there's no reason or incentive** to want to put that into your source control. At worst, it will also bloat your repository, filling your diffs with things you simply don't control and don't necessarily want to review.

I would not expect different Git branches of an NPM project to contain different node_modules folders. I'd only expect the one node_modules folder, and if a branch gave me fits about dependencies, I'd look to reinstall the dependencies (and note it down to be sure that something else hadn't gone awry).

As an addendum, any files or folders in .gitignore are simply not indexed or tracked by Git. If the contents of those files or folders change, Git is none the wiser. This also means, when switching between branches, the contents of the files or folders in .gitignore remain the same.

*: Provided that the library you're using isn't suddenly yanked. Or the repository is not impacted by a colossal DDoS.

**: There may be some incentive to do this given that the reliability of certain NPM packages hasn't been 100% this year, but that's a team and architecture-driven decision, and I doubt that placing it into source control is the most ideal and convenient way to deal with it.

like image 193
Makoto Avatar answered Oct 24 '22 05:10

Makoto


There are two schools of thought, and both have merit.

1) Never check in node_modules and rebuild on deploy/install

The approach relies heavily on NPM and the connectivity of your deploy environment. node_modules are downloaded and installed (and/or compiled) each time the deploy is run.

Positives: Your repository is much smaller.

NPM modules are installed in the environment they will run on.

Concerns: Tied to 3rd party for sources - Go read about that whole left-pad thing. If one dependency cannot be downloaded, your entire build system is hung out to dry. "Cranky and paranoid old timers" will cite this as the reason to check everything in (or run your own private NPM somewhere).

Branch management - Like you mentioned in the question, some branches might not have the same dependencies. Dev1 adds a new features and used a new package. Now Dev2 runs the dev branch or whatever, and everything is broken and they need to know to npm install the new package. More subtle is the case where a npm package is version changed (now you need npm update as npm install will say nothing has changed), or where their node_modules are upgraded to work on "new feature 10" but they need to clear everything out to "downgrade" to go fix "prior bug 43". If you are in active development with a team of more than 2-3, watch out for this one.

Build Time - If it is a concern, it takes a little longer to download and install everything. Or a lot longer.

2) Always check in everything you can

This approach includes node_modules as part of the repo.

Positives: Not dependent on 3rd party sources. You have what you need to run. You code can live on its own forever, and it does not matter if npm is down or a repo is deleted.

Branches are independent, so new features from Dev1 are auto included when Dev2 switches to that branch

Deploy time is shorter because not much needs to be installed.

Concerns: Repository is much larger. Clones of code take longer as there are many more files.

Pull Requests need extra care. If a package is updated (or installed) along with core code, the PR is a mess and sometimes unintelligible. "500 files changed", but really you updated a package and changed two lines of core code. It can help to break down into two PRs - one that is is a mess (the package update) and one that is actually reviewable (the core code change). Again, be prepared for this one. The packages will not change too often, but your code review takes a little longer (or a little more care) when they do.

OS Dependent Packages can break. Basically anything that is installed/compiled with gyp can be OS dependent (among others). Most packages are "pure JS" and, being just scripts, run everywhere. Imagine all your devs run and test on OSX while you deploy to Linux, you cannot check in those packages that were compiled on a MAC because they will not run on Linux. An odd workaround for this is to define most packages as "dev dependencies" (--save-dev) and the ones that need compiled as normal ("production", --save), then you run npm install --production so the dev dependencies are not installed (and are already present), but the others are.

Conclusions

It depends. (Don't you hate hearing that all the time? : )

Depending on your team and your concerns, you might go either approach. Both have their merits, and you will decide which is more beneficial to you. Both have drawbacks as well, so be aware of those before you get bit!

like image 11
clay Avatar answered Oct 24 '22 05:10

clay