I would like to deploy a nodejs project with frequent updates. npm is not available at the site so I must package the node_modules. This works ok but takes a long time to send to the customer over the available ftp connection (80MB of mostly node_module files every time). My workflow looks like this:
git clone project
npm install # installs all my dev tools which I need for packaging
grunt build
tar xvzf build.tar.gz build/
The build step minfifies my code packaging only what is needed. The node_modules folder is copied into the build folder. If I use npm install --production
, I get a smaller footprint but miss the tools I need to build it in the first place. So in the end I go to some effort to make my code footprint small but all my work is undone by having to package such a large node_modules tree.
Is my approach wrong? Is there a simpler way to deploy where npm is not available on the production server or is there a good way to reduce the size of the node_modules folder?
I have compiled the list of findings below for anyone looking to
Use npm prune --production to remove devDependencies and purge additional modules
In my case this node_modules folder size by about 20%.
The drawback is that npm install has to be run before each build.
Manualy purge unwanted folders
The bulk of large files under node_modules folders is confined to a small number of modules that are unused at runtime!. Purging/deleting these reduces the footprint by a factor of 10! In my case these include: karma, bower, less and grunt. Many of these are used by the modules themselves and have no place in a production build.
npm-flatten/dedupe
There is supposedly a lot of duplication in the node_modules tree. npm-dedupe did not make much difference for me. I see npm-flatten may be an alternative but I have not tested it.
npm-package-minifier may be used to reduce the size of the node_modules tree
Compacting node_modules for client-side deployment
This basically deletes a lot of unused files in the node_modules tree. This tool will reduce the size of devDependencies also so it should be run on a 'production' verison of node_modules.
Use partial npm packages
Many npm packages are available in part. e.g. instead of using async, use async.waterfall or lodash.foreach instead of lodash if space is an issue.
Differential deployment
As mentioned in one of the comments above a updates could be split into those where changes to npm are required and those where only application logic changes. I have been using such a strategy but, in my opinion, it increases the complexity of deployment, can lead to error and should not be necessary.