1

Every time I push to heroku it simply says "Not Found". I am assuming it is because webpack doesn't run?

I've tried all sorts of scripts:

"scripts": {
  "clean": "rimraf dist",
  "build": "npm run clean && NODE_ENV=production && webpack -p --progress",
  "postinstall": "npm run builds",
  "serve": "webpack-dev-server"
}

and another, just without the postinstall.

The one with the postinstall will give me an error, saying webpack wasn't installed (saved under my devDependencies). In the second I get a successful build on the Heroku log but "Not Found" when I load the page.

user2465134
  • 8,793
  • 5
  • 32
  • 46

2 Answers2

7

You need to put webpack (as well as any other dependencies that you need on Heroku) under "dependencies" in your package.json, not under "devDependencies".

Yoni Rabinovitch
  • 5,171
  • 1
  • 23
  • 34
  • That's what I figured but I see so many people putting them under devDependencies. Do you know why that is? – user2465134 Feb 01 '17 at 12:44
  • 3
    Heroku is a production environment. The devDependencies are for packages that are required on your development environment only. Packages that you need to be included in your Heroku slug (including packages required during the slug build phase, such as webpack), need to be in your dependencies, not devDependencies. It is possible that you see people putting webpack in devDependencies for other platforms, but probably not for Heroku. – Yoni Rabinovitch Feb 01 '17 at 20:12
  • 2
    But if you are really adamant about installing your devDependencies on Heroku (not recommended), you can do it by setting NPM_CONFIG_PRODUCTION=false, as explained here: https://devcenter.heroku.com/articles/nodejs-support#devdependencies – Yoni Rabinovitch Feb 01 '17 at 20:18
  • Yeah I saw that but I don't want to go down that road. Gonna just fix my dependencies. Thanks! – user2465134 Feb 01 '17 at 22:43
  • 1
    You can always use the `postinstall` npm hook to run a script that can check to see if you're on Heroku (so it doesn't run locally or elsewhere), load your dev dependencies, run your build, then remove the dev dependencies. The build takes longer, but the downtime shouldn't be any different, and your `package.json` stays clean. That's how we're managing our environments so we can still use auto-deployments from GitHub. – Nathan Loyer Feb 14 '17 at 22:42
3

I think a better way to handle this is to keep your package.json clean, and since Heroku makes it harder to build things, just handle that specific case.

We use the NPM postinstall hook to perform build tasks, load dev dependencies for those tasks, cleanup, etc.

From the scripts section of your package.json:

"scripts": { 
  "postinstall": "node ./ops/heroku-build.js" 
}

And heroku-build.js:

'use strict';

if ('HEROKU' in process.env || ('DYNO' in process.env && process.env.HOME === '/app')){

  const pkg = require('../package.json');
  const ChildProcess = require('child_process');


  let deps = pkg.devDependencies;
  let packages = "";

  Object.keys(deps).forEach((key) => {
    packages += `${key}@${deps[key]} `; // note space at end to separate entries
  });

  try {
    console.time("install");
    console.log("starting npm install of dev dependencies");
    ChildProcess.execSync(`npm install ${packages}`);
    console.timeEnd("install");

    console.time("build");
    console.log("starting npm build");
    ChildProcess.execSync(`npm run build:all`);
    console.timeEnd("build");

    console.time("uninstall");
    console.log("starting npm uninstall of dev dependencies");
    ChildProcess.execSync(`npm uninstall ${packages}`);
    console.timeEnd("uninstall");
  }
  catch (err) {
    console.error(err.message);
  }
} else {
  console.log("Not Heroku, skipping postinstall build");
}

That way if we decide to deploy to AWS or somewhere else in the future, we can handle the idiosyncrasies of their environment separately.

Heroku documentation on how to customize the build process.

Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
Nathan Loyer
  • 1,339
  • 10
  • 20
  • 3
    Nice, although somewhat complex for someone just trying to get his first app up on Heroku! – Yoni Rabinovitch Feb 15 '17 at 06:51
  • I suppose that's true. But it never hurts to have some idea how to handle these things as you start down the Heroku path! Overall, I think it's just good to understand the Heroku build stages. – Nathan Loyer Feb 16 '17 at 13:55
  • 1
    You could do that without a script. I find that parsing the `package.json` and manually doing npm's work is fragile and not worth it. – Emile Bergeron Apr 24 '17 at 20:59
  • 1
    @EmileBergeron please elaborate "You could do that without a script." in an answer! – TWiStErRob Oct 21 '17 at 13:36
  • @TWiStErRob very late, but it would be `npm prune --production`. [Another answer of mine](https://stackoverflow.com/a/43463456/1218980) on a similar question was linking to [another Nathan's answer](https://stackoverflow.com/a/43522339/1218980) which led me back here. – Emile Bergeron Apr 07 '20 at 16:13