Clean Heroku npm cache
Today I ran into an issue with Heroku and the way its official buildpack for Node caches node_modules
. Namely, I was forced to fork a couple of modules so I updated package.json
to point to GitHub repositories (see this tip).
Unfortunately, Heroku stubbornly refused to modules from the updated path and actually npm
wasn't behaving much better on my local machine either but there at least I could manually delete the node_modules
and re-install everything. Committing and pushing minor updates to package.json
didn't help so I finally looked into buildpack's code
It turns out that it always runs npm prune
on cached modules so I decided to leverage that. So to clear the modules cache:
- I removed all the modules from the
package.json
- Committed and pushed that change to Heroku
- Waited for the buildpack to prune the cache
- Returned all the modules to
package.json
- Committed and pushed again to Heroku
After that Heroku correctly downloaded my forked modules.
UPDATE: See below for a recommendation that I hadn't tried but that doesn't feel hacky as hell:
heroku config:set NODEMODULESCACHE=false
git commit -am 'rebuild' --allow-empty
git push heroku master
heroku config:unset NODEMODULESCACHE
Written by Ivan Erceg
Related protips
8 Responses
Helped a lot, thanks.
I couldn't understand why heroku wouldn't pick up the new version of a module in package.json, but it did after I followed this procedure.
That doesn't work well for production instances. This is a better solution:
heroku config:set NODEMODULESCACHE=false
git commit -am 'rebuild' --allow-empty
git push heroku master
heroku config:unset NODEMODULESCACHE
lol. Coderwall does not want text to contain underscores at all!
NODEMODULESCACHE
should be
NODE_MODULES_CACHE
The documentation is here - https://devcenter.heroku.com/articles/nodejs-support#cache-behavior and it works.
heroku config:set NODE_MODULES_CACHE=false
git commit -am 'rebuild' --allow-empty
git push heroku master
heroku config:unset NODE_MODULES_CACHE
Hi. I'm the heroku node buildpack maintainer.
You can certainly get this behavior by disabling the cache (which is effectively the same thing as deleting node_modules
locally). In some instances, that will be the only way, because of how npm works with git dependencies.
However, in most cases it's a much better idea to specify better versions in package.json. For instance, if you specify "*" it means "this app works with literally any version of the dependency," so once that dependency is installed once, it will never be updated unless you disable the cache. Use npm install --save --save-exact mydependency
to save exact versions of dependencies to package.json for more reliable npm installs everywhere, every time.
Thanks for jumping in - I appreciate it. The "*" versions are just awful - I've outlawed them outright.
Ssh-ing and deleting node_modules
is an obvious idea - I wish I had thought of it.
So the recommendations would be:
- For all dependencies, always specify the exact version.
- If you have any
git
dependencies, disable the caching withNODE_MODULES_CACHE=false
@iabw - thanks for pointing out the docs. That seems to be a very recent addition - glad to see the problem tackled in a non-hacky way.
For users with non-official node buildpacks (like strongloop-buildpack), it may not support NODE_MODULES_CACHE
toggle. In this case, the heroku-repo plugin can be pretty handy: https://github.com/heroku/heroku-repo#purge_cache
Hey. None of the above worked for me.
Node modules were staying cached for some absurd reason.
The following by heroku did help:
https://help.heroku.com/18PI5RSY/how-do-i-clear-the-build-cache
$ heroku plugins:install heroku-repo
$ heroku repo:purge_cache -a appname
$ git commit --allow-empty -m "Purge cache"
$ git push heroku master