babel-node is not getting installed on Heroku

2.6k Views Asked by At

I'm using babel-node for ES6 syntax on Heroku, but I get a build error when I deploy. It says "babel-node: not found". I've tried a clean install on my local computer and it works perfectly. Package.json:

{
  "name": "secret",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "./node_modules/.bin/babel-node ./bin/www"
  },
  "engines": {
    "node": "7.5.0",
    "npm": "5.0.3"
  },
  "dependencies": {
    "babel-cli": "^6.24.1",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-stage-0": "^6.24.1",
    ...
  }
}

I appreciate your help! :)

2017-07-17T11:02:26.997876+00:00 heroku[web.1]: State changed from crashed to starting
2017-07-17T11:02:31.839278+00:00 heroku[web.1]: Starting process with command `npm start`
2017-07-17T11:02:38.074157+00:00 heroku[web.1]: State changed from starting to crashed
2017-07-17T11:02:38.062607+00:00 heroku[web.1]: Process exited with status 1
2017-07-17T11:02:37.865774+00:00 app[web.1]:
2017-07-17T11:02:37.865786+00:00 app[web.1]: > [email protected] start /app
2017-07-17T11:02:37.865787+00:00 app[web.1]: > babel-node ./bin/www
2017-07-17T11:02:37.865787+00:00 app[web.1]:
2017-07-17T11:02:37.936361+00:00 app[web.1]: sh: 1: babel-node: not found
2017-07-17T11:02:37.966452+00:00 app[web.1]: npm ERR! file sh
2017-07-17T11:02:37.966683+00:00 app[web.1]: npm ERR! code ELIFECYCLE
2017-07-17T11:02:37.966931+00:00 app[web.1]: npm ERR! errno ENOENT
2017-07-17T11:02:37.967106+00:00 app[web.1]: npm ERR! syscall spawn
2017-07-17T11:02:37.967287+00:00 app[web.1]: npm ERR! [email protected] start: `babel-node ./bin/www`
2017-07-17T11:02:37.967430+00:00 app[web.1]: npm ERR! spawn ENOENT
2017-07-17T11:02:37.967588+00:00 app[web.1]: npm ERR!
2017-07-17T11:02:37.967733+00:00 app[web.1]: npm ERR! Failed at the [email protected] start script.
2017-07-17T11:02:37.967873+00:00 app[web.1]: npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
2017-07-17T11:02:37.969151+00:00 app[web.1]:
2017-07-17T11:02:37.969374+00:00 app[web.1]: npm ERR! A complete log of this run can be found in:
2017-07-17T11:02:37.969484+00:00 app[web.1]: npm ERR!     /app/.npm/_logs/2017-07-17T11_02_37_957Z-debug.log
2017-07-17T11:25:52.044791+00:00 heroku[web.1]: State changed from crashed to starting
2017-07-17T11:25:54.841341+00:00 heroku[web.1]: Starting process with command `npm start`
2017-07-17T11:25:57.407691+00:00 heroku[web.1]: Process exited with status 1
2017-07-17T11:25:57.413873+00:00 heroku[web.1]: State changed from starting to crashed
2017-07-17T11:25:57.310176+00:00 app[web.1]:
2017-07-17T11:25:57.310190+00:00 app[web.1]: > [email protected] start /app
2017-07-17T11:25:57.310191+00:00 app[web.1]: > babel-node ./bin/www
2017-07-17T11:25:57.310192+00:00 app[web.1]:
2017-07-17T11:25:57.316940+00:00 app[web.1]: sh: 1: babel-node: not found
2017-07-17T11:25:57.335019+00:00 app[web.1]: npm ERR! file sh
2017-07-17T11:25:57.335287+00:00 app[web.1]: npm ERR! code ELIFECYCLE
2017-07-17T11:25:57.335517+00:00 app[web.1]: npm ERR! errno ENOENT
2017-07-17T11:25:57.335735+00:00 app[web.1]: npm ERR! syscall spawn
2017-07-17T11:25:57.335933+00:00 app[web.1]: npm ERR! [email protected] start: `babel-node ./bin/www`
2017-07-17T11:25:57.336095+00:00 app[web.1]: npm ERR! spawn ENOENT
2017-07-17T11:25:57.336280+00:00 app[web.1]: npm ERR!
2017-07-17T11:25:57.336449+00:00 app[web.1]: npm ERR! Failed at the [email protected] start script.
2017-07-17T11:25:57.336614+00:00 app[web.1]: npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
2017-07-17T11:25:57.337985+00:00 app[web.1]:
2017-07-17T11:25:57.338232+00:00 app[web.1]: npm ERR! A complete log of this run can be found in:
2017-07-17T11:25:57.338379+00:00 app[web.1]: npm ERR!     /app/.npm/_logs/2017-07-17T11_25_57_323Z-debug.log
2

There are 2 best solutions below

1
On

babel-node is "not meant for production use". There is a more relevant guide here for using @babel/cli, @babel/core and @babel/preset-env.

The babel dependencies should all be installed as devDependencies and you should transpile your code during in a build script run before Heroku prunes the devDependencies. See this guide

If you move all of your es6 code into a common directory like src at the top level of your app, you can create a build script to transpile everything in that directory to an output directory like build.

"build": "npm run clean && npm run build-babel",
"build-babel": "./node_modules/.bin/babel -d ./build ./src",
"clean": "rm -rf build && mkdir build",

In the example above, the build script will be run automatically by Heroku. clean will create a new build directory, and build-babel will transpile the code and place it in the build directory. After this is completed, Heroku will prune the devDependencies, but you will no longer need Babel.

When Heroku calls start below, it will be running your transpiled code. You should no longer see sh: 1: babel-node: not found.

"scripts": {
  "build": "npm run clean && npm run build-babel",
  "build-babel": "./node_modules/.bin/babel -d ./build ./src",
  "clean": "rm -rf build && mkdir build",
  "start": "node ./build/bin/www"
},

One potential gotcha, Do not call build from your start script. If you do, the devDependencies will have been pruned and you will get the following

sh: 1: babel: not found

0
On

A little bit late, but here is what I think you are missing:

Step (1): npm install --save babel-cli babel-preset-env in terminal

Note on step 1: Do not save to dev as that will require you to set NPM_CONFIG_PRODUCTION=false

Step (2): You are not compiling anything to babel without adding in the babel boilerplate and or using a babelrc file. Easiest method is to make a .babelrc file in your main app folder, ie. same one your package.json is in and input the following:

 {
  "presets": ["env"]
}

Note on step 2: With the usage of the env preset you do not need the babel-preset-es2015, etc

Step (3): You can now run your code using babel-node, so in your case execute your start script, ie. ./node_modules/.bin/babel-node ./bin/www

I suggest reading through the NPM module if you need further guidance understanding the preset logic: https://www.npmjs.com/package/babel-preset-env

Furthermore, I would suggest using a process manager like pm2. This allows your node instance to keep alive if it crashes. The forever module used to do this but pm2 is way better. Here is an example of a start script inside your package.json:

"scripts": { "start": "node ./node_modules/.bin/pm2 start main.json --attach --env production" }

Procfile (note, I am using nginx but just npm start would work fine):

web: bin/start-nginx npm start 
worker: node ./node_modules/.bin/pm2 start worker.json --attach

And here would be your main.json with args to use babel-node (note, keep instance to 1 and do not fork on a web dyno in Heroku):

main.json:

{
  "name": "the_awesome",
  "script": "app.js",
  "instances": 1,
  "exec_mode": "cluster"
}

worker.json:

{
  "name": "worker",
  "script": "/app/lib/worker.js"
}

(4) Add a require('babel-register') hook to your app.js and worker.js if you are using pm2 in cluster mode. If you are using pm2 not in cluster mode, or just not using pm2 then you can use babel-node directly to run your .js or es6 files

Finally, to check if babel-node is really installed you can do the following:

 heroku run bash -a {name of your app}
 ls ./node_modules/.bin //babel-node should be present

Good luck!