Last Updated: September 16, 2018
·
30.74K
· ierceg

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:

  1. I removed all the modules from the package.json
  2. Committed and pushed that change to Heroku
  3. Waited for the buildpack to prune the cache
  4. Returned all the modules to package.json
  5. 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

8 Responses
Add your response

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.

over 1 year ago ·

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

over 1 year ago ·

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
over 1 year ago ·

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.

over 1 year ago ·

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:

  1. For all dependencies, always specify the exact version.
  2. If you have any git dependencies, disable the caching with NODE_MODULES_CACHE=false
over 1 year ago ·

@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.

over 1 year ago ·

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

over 1 year ago ·

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

over 1 year ago ·