I followed the basic getting started instructions for node.js on Heroku here:
https://devcenter.heroku.com/categories/nodejs
These instruction don't tell you to create a .gitignore node_modules, and therefore imply that node_modules should be checked in to git. When I include node_modules in git my getting started application ran correctly.
When I followed the more advanced example at:
https://devcenter.heroku.com/articles/realtime-polyglot-app-node-ruby-mongodb-socketio https://github.com/mongolab/tractorpush-server (source)
It instructed me to add node_modules to .gitignore. So I removed node_modules from git, added it to .gitignore, then re-deployed. This time the deployed failed like so:
-----> Heroku receiving push
-----> Node.js app detected
-----> Resolving engine versions
Using Node.js version: 0.8.2
Using npm version: 1.0.106
-----> Fetching Node.js binaries
-----> Vendoring node into slug
-----> Installing dependencies with npm
Error: npm doesn't work with node v0.8.2
Required: node@0.4 || 0.5 || 0.6
at /tmp/node-npm-5iGk/bin/npm-cli.js:57:23
at Object.<anonymous> (/tmp/node-npm-5iGk/bin/npm-cli.js:77:3)
at Module._compile (module.js:449:26)
at Object.Module._extensions..js (module.js:467:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:362:17)
at require (module.js:378:17)
at Object.<anonymous> (/tmp/node-npm-5iGk/cli.js:2:1)
at Module._compile (module.js:449:26)
Error: npm doesn't work with node v0.8.2
Required: node@0.4 || 0.5 || 0.6
at /tmp/node-npm-5iGk/bin/npm-cli.js:57:23
at Object.<anonymous> (/tmp/node-npm-5iGk/bin/npm-cli.js:77:3)
at Module._compile (module.js:449:26)
at Object.Module._extensions..js (module.js:467:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:362:17)
at require (module.js:378:17)
at Object.<anonymous> (/tmp/node-npm-5iGk/cli.js:2:1)
at Module._compile (module.js:449:26)
Dependencies installed
-----> Discovering process types
Procfile declares types -> mongod, redis, web
-----> Compiled slug size is 5.0MB
-----> Launching... done, v9
Running "heroku ps" confirms the crash. Ok, no problem, so I rolled back the change, add node_module back to the git repository and removed it from .gitignore. However, even after reverting, I still get the same error message on deploy but now the application is running correctly again. Running "heroku ps" tells me the application is running.
So my question is what's the right way to do this? Include node_modules or not? And why would I still be getting the error message when I rollback? My guess is the git repository is in a bad state on the Heroku side?
I am using this solution:
node_modules
. If you have native modules that should be build for specific platform then create separate repository for each platform.git submodule
:git submodule add .../your_project_node_modules_windows.git node_modules_windows
git submodule add .../your_project_node_modules_linux_x86_64 node_modules_linux_x86_64
node_modules
tonode_modules
directory and addnode_modules
to.gitignore
.npm install
.So you can easily switch between
node_modules
on different platforms (for example if you are developing on OS X and deploying to Linux).My biggest concern with not checking
node_modules
into git is that 10 years down the road, when your production application is still in use, npm may not be around. Or npm might become corrupted; or the maintainers might decide to remove the library that you rely on from their repository; or the version you use might be trimmed out.This can be mitigated with repo managers like maven, because you can always use your own local Nexus or Artifactory to maintain a mirror with the packages that you use. As far as I understand, such a system doesn't exist for npm. The same goes for client-side library managers like Bower and Jamjs.
If you've committed the files to your own git repo, then you can update them when you like, and you have the comfort of repeatable builds and the knowledge that your app won't break because of some third-party action.
From https://web.archive.org/web/20150212165006/http://www.futurealoof.com/posts/nodemodules-in-git.html :
Edit: The original link was this one but it is now dead. Thanks @Flavio for pointing it out.
My favorite part:
scenario 1:
One scenario: You use a package that gets removed from npm. If you have all the modules in the folder node_modules, then it won't be a problem for you. If you do only have the package name in the package.json, you can't get it anymore. If a package is less than 24 hours old, you can easily remove it from npm. If it's older than 24 hours old, then you need to contact them. But:
read more
So the chances for this are low, but there is scenario 2...
scenario 2:
An other scenario where this is the case: You develop an enterprise version of your software or a very important software and write in your package.json:
You use the method
function1(x)
of that package.Now the developers of studpid-package rename the method
function1(x)
tofunction2(x)
and they make a fault... They change the version of their package from1.0.1
to1.1.0
. That's a problem because when you callnpm install
the next time, you will accept version1.1.0
because you used the tilde ("studpid-package": "~1.0.1"
).Calling
function1(x)
can cause errors and problems now.Pushing the whole node_modules folder (often more than 100 MB) to your repository, will cost you memory space. A few kb (package.json only) compared with hundreds of MB (package.json & node_modules)... Think about it.
You could do it / should think about it if:
the software is very important.
it costs you money when something fails.
you don't trust the npm registry. npm is centralized and could theoretically be shut down.
You don't need to publish the node_modules folder in 99.9% of the cases if:
you develop a software just for yourself.
you've programmed something and just want to publish the result on GitHub because someone else could maybe be interested in it.
If you don't want the node_modules to be in your repository, just create a
.gitignore
file and add the linenode_modules
.I have been using both committing node_modules folder and shrink-wrapping. Both solutions did not make me happy.
In short: committed node_modules adds too much noise to repository.
And shrinkwrap.json is not easy to manage and there is no guarantee that some shrink-wrapped project will build in a few years.
I found that Mozilla was using a separate repository for one of their projects https://github.com/mozilla-b2g/gaia-node-modules
So it did not take me long to implement this idea in a node CLI tool https://github.com/bestander/npm-git-lock
Just before every build add
npm-git-lock --repo [git@bitbucket.org:your/dedicated/node_modules/git/repository.git]
It will calculate hash of your package.json and will either check out node_modules content from a remote repo, or, if it is a first build for this package.json, will do a clean
npm install
and push the results to the remote repo.Second Update
The FAQ is not available anymore.
From the documentation of
shrinkwrap
:Shannon and Steven mentioned this before but I think, it should be part of the accepted answer.
Update
The source listed for the below recommendation has been updated. They are no longer recommending the
node_modules
folder be committed.Original Post
For reference, npm FAQ answers your question clearly:
and for some good rationale for this, read Mikeal Rogers' post on this.
Source: https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git