How can I make Heroku install devDependencies?

HerokuNpmGruntjsDependency Management

Heroku Problem Overview


I would like to have Heroku build my app after I push it so that I don't have to push the build folder up every time I make a change. However Heroku only installs the dependencies from the package.json and grunt (my build tool) and all of its components are in devDependencies. I would like to keep them there where they belong. What's the workaround here?

Heroku Solutions


Solution 1 - Heroku

UPDATE: as pointed out in the comments this is no more needed because since 2018 heroku changed its default behaviour and dev dependencies are automatically installed

ORIGINAL ANSWER

Heroku by default installs only the production dependencies, ignoring the development dependencies under devDependencies.

Setting the npm production variable to false do the trick:

heroku config:set NPM_CONFIG_PRODUCTION=false

More info are available at the Heroku Node.js Support page.

Solution 2 - Heroku

Keeping NPM_CONFIG_PRODUCTION true, I used Heroku's script hooks:

"scripts": {
  ...
  "heroku-prebuild": "export NPM_CONFIG_PRODUCTION=false; export NODE_ENV=; NPM_CONFIG_PRODUCTION=false NODE_ENV=development npm install --only=dev --dev",
  "heroku-postbuild": "export NPM_CONFIG_PRODUCTION=true; export NODE_ENV=production;",
   ...
},

(Finally) worked for me.

Solution 3 - Heroku

scripts": {
  ...
  "heroku-prebuild": "npm install --only=dev"
}

This was enough for me. Thanks to PixnBits for the hint about heroku-prebuild. Also - my problem was with babel. I ended up moving babel-preset-es2015 and other presets into dependencies otherwise babel complained about presets.

Update: 8/11/2017 I've been having trouble with this. It seems like things have changed (and npm is on 5.3 now). But what I see is that the heroku-prebuild script is getting run, and then the post-install script is getting run (but I was only trying to install -dev).

So what I have been doing that works is to just run:

heroku config:set NPM_CONFIG_PRODUCTION=false

And just leave it set that way. I'd love a better solution.

Solution 4 - Heroku

To unintall dependencies you need to do these

  1. Update NPM_CONFIG_PRODUCTION

    heroku config variable set

    NPM_CONFIG_PRODUCTION=false

  2. Add heroku-prebuild:

    scripts": {
      ...
      "heroku-prebuild": "npm install"
    }

or

    scripts": {
      ...
      "heroku-prebuild": "npm install --only=dev"
    }

Solution 5 - Heroku

you can use this in your build script "build": "npm install --only=dev" should in case you still want to perform more operations e.g transpiling your code with babel you can do something like this "build": "npm install --only=dev && babel src --out-dir dist --copy-files"

Solution 6 - Heroku

Since 1 March 2018 Heroku installs devDependencies by default, and then prunes them after the build step is done:

> By default, Heroku will install all dependencies listed in > package.json under dependencies and devDependencies. > > After running the installation and build steps Heroku will strip out > the packages declared under devDependencies before deploying the > application. > > Heroku uses the lockfiles, either the package-lock.json or yarn.lock, > to install the expected dependency tree, so be sure to check those > files into git to ensure the same dependency versions across > environments.

Link

Solution 7 - Heroku

I found this highly confusing. Even though Heroku says that their default since 2018 is to install all dependencies, they also set the env var NODE_ENV=production by default. This is good because it causes/allows for pruning, but it is bad because it means NPM will not install devDependencies.

To avoid this without messing with environment variables and their possible side effects, we can append --production=false to npm and it will install dependencies and devDependencies.

In our case, in package.json in scripts we have a line:

"install": "npm i --prefix ... --production=false"

My answer similar to others above with the additional references that seem to explain why it's not actually working by default like Heroku suggests.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionionox0View Question on Stackoverflow
Solution 1 - HerokuEdoView Answer on Stackoverflow
Solution 2 - HerokuPixnBitsView Answer on Stackoverflow
Solution 3 - HerokuDavid FridleyView Answer on Stackoverflow
Solution 4 - HerokuRobert Anthony S. TribianaView Answer on Stackoverflow
Solution 5 - HerokuotoloyeView Answer on Stackoverflow
Solution 6 - HerokuvalentinView Answer on Stackoverflow
Solution 7 - HerokuJohn LehmannView Answer on Stackoverflow