88

I have been developing a site using babel-node and browserify with the babelify transform, to support ES6 syntax.

I am just wondering, can I run this in production as babel-node server rather than node server What other options do I have to run ES6 in node?

Here are the commands I am running for build and start in development

// npm run build
browserify -t [babelify] client.js > public/js/bundle.js",

// npm start
babel-node server.js"

Here are my dev dependencies

"babel": "^4.0.1",
"babelify": "^5.0.3",
"browserify": "^8.0.3"
svnm
  • 22,878
  • 21
  • 90
  • 105

4 Answers4

117

For the client side code, you're doing the correct thing. babelify it and ship it to the client.


For the server side code, I would just do a regular build using babel-cli

According to http://babeljs.io/docs/setup/#babel_register, babel-register is not meant for production use — The require hook is primarily recommended for simple cases.

for Babel 6+

As of Babel 6, no transformations are included by default. So let's start by installing babel-cli and babel-preset-es2015.

$ npm install --save-dev babel-cli babel-preset-es2015

Add a transformation to your .babelrc file — this is the prest module we downloaded above. Take a look at the full list of presets to see which one(s) are a best fit for you.

{
  "presets": ["es2015"]
}

Add a build script to your package.json. Below src is your input files and build is the transformed output files

"scripts": {
  "build": "babel src -d build"
}

Then build it!

$ npm run build

Then run your code. At this point, you'll want to be executing the files in your build directory

$ npm start

for Babel <= 5, just use the require hook.

require("babel/register");

All subsequent files required by node with the extensions .es6, .es, .jsx and .js will be transformed by Babel. The polyfill is also automatically required.

You will be able to keep your source files in ES6 but still execute them using node server.js


According to your comments, you seem to be having a little trouble. Pay particular attention to the yellow highlighted part above. Your first file can only be ES5, which is run by node itself. All subsequent requires will be transformed by Babel...

Here's what a typical setup might look like

server.js

// only ES5 is allowed in this file
require("babel/register");

// other babel configuration, if necessary

// load your app
var app = require("./app.js");

app.js

// this file will be loaded through babel
// you can now use ES6 here and in every other include

fire it up!

$ node server.js
Mulan
  • 129,518
  • 31
  • 228
  • 259
  • 9
    Actually I just tried this, putting `require("babel/register");` in my server.js and when I run `node server.js` I get the error: `Unexpected reserved word: import ...` so it didn't seem to work – svnm Jun 12 '15 at 03:53
  • 1
    @steveniseki my update should demonstrate how to get things up and running. – Mulan Jun 13 '15 at 05:57
  • Awesome, thanks a lot for that, I actually assumed that would be the case and tried making my server.js all in ES5 but it didn't seem to work, anyway this solution is actually much nicer pushing the app to an app.js, and it worked perfectly. Thanks – svnm Jun 13 '15 at 12:58
  • The example project which now works in this fashion with node server.js :) is [here](https://github.com/goatslacker/isomorphic-react-examples/tree/master/react-router/react-router-movies) if anyone is interested to see the example. It is an example using react router, babel and alt, which I will be using for a real site. – svnm Jun 13 '15 at 13:00
  • 4
    meanwhile it changed to require("babel-register"); .. anyway I get "Unexpected token import" .. – smotru Nov 30 '15 at 20:05
  • maybe this [post](https://github.com/gulpjs/gulp/issues/1359) can help you guys, i assume you're all use babel 6 ver – anztrax Dec 04 '15 at 05:07
  • For the client side, is it ok for mobile webapp? I just worry about the size of the compiled file since I may also use react. – Tinple Feb 03 '16 at 03:29
  • If you are using Node.js 7 you probably don't need Babel anymore: http://node.green/ – jonathancardoso Jan 23 '17 at 18:03
  • Need to keep all my exist files to `src` ? like `Dockerfile`, `package.json`, `index.js` – 151291 Nov 22 '19 at 06:40
58

I just wrote a blog post on this topic

Babeljs CLI documentation warns the following:

babel-node not meant for production use

You should not be using babel-node in production. It is unnecessarily heavy, with high memory usage due to the cache being stored in memory. You will also always experience a startup performance penalty as the entire app needs to be compiled on the fly.

This is an example of how you could set up the npm scripts to run your app with node instead of babel-node.

"scripts": {
  "clean": "rm -rf build && mkdir build",
  "build-css": "node-sass scss/app.scss public/css/app.css",
  "build-server": "babel -d ./build ./server -s",
  "build": "npm run clean && npm run build-css && npm run build-server",
  "lint": "eslint source/ --quiet",
  "start": "node ./build/index.js",
  "debug": "node --debug ./build/index.js",
  "test": "for i in $(ls tests/); do babel-node \"./tests/${i}\" | faucet ; done",
  "validate": "npm run lint; npm run test && npm outdated --depth 0"
},

You can find more details on the blog post

cuadraman
  • 14,964
  • 7
  • 27
  • 32
  • 3
    Since Node 4.0 support ES6, do we still need to use babel to compile the code? – lvarayut Oct 30 '15 at 11:16
  • 8
    @LVarayut Yes, depending on the features, babel is still needed server side. Node v4.0.0 does not support all ES6 features (especially modules via import/export syntax). See https://nodejs.org/en/docs/es6/ for more information on the topic, or type node --v8-options | grep "in progress" in a terminal to get a list of not yet implemented ES6 features. – jbmusso Oct 30 '15 at 13:46
  • 14
    Babel is not only for ES6, but for ESNext.. So it continuously adds features from ES7 and the latest as soon as they get settled in the TC39 spec. – cuadraman Oct 30 '15 at 17:28
15

It's important to weigh the pros and cons of using babel-node in production.

  • babel-node does add between half a second to one second to the startup cost, on commodity hardware. But if your app is a long-running server, that startup cost won't matter much.
  • Try to measure the extra memory consumption. For my app for example (reading and processing time series data), it was only 20MB. Depending on your situation, this may or may not be significant.

On the other hand,

  • using babel-node directly simplifies development - you won't need "build" scripts, and you won't have separate src/lib and dist directories
  • if you import from local files, will you import from src/myutils, or from lib/myutils? Using babel-node eliminates that problem.

I only use Babel for modules support. Now V8 just released support for modules on January 10, 2017. Hopefully we'll see modules support in Node under a flag in a few months, rendering my reason for using Babel moot.

Dan Dascalescu
  • 143,271
  • 52
  • 317
  • 404
9

@cuadraman's answer is more accurate than @naomik.

To answer your question briefly: no, babel-node shouldn't be invoked explicitly by you. babel-node is a private library that's consumed by babel-cli.

The official tutorial has everything you need to get up and running on node (not browser-side!): https://github.com/babel/example-node-server. READ IT! I found so many misleading blog tutorials that used round about ways, and found this article the easiest to follow.

Bonus: contrary to what many people think, all of the transpiling magic can be installed locally (using npm install --save-dev babel-cli nodemon babel-preset-es2015 babel-preset-stage-2). No need to install Babel or any of its helper modules globally! Pretty nifty.

wle8300.com
  • 2,588
  • 1
  • 23
  • 29