Skip to content

Instantly share code, notes, and snippets.

@rauchg
Last active July 11, 2023 09:38
Show Gist options
  • Save rauchg/93d8b831e286bcb30d84 to your computer and use it in GitHub Desktop.
Save rauchg/93d8b831e286bcb30d84 to your computer and use it in GitHub Desktop.
Writing ES6 today, effectively.

Effective transpiling of ES6

After publishing my article on ECMAScript 6, some have reached out to ask how I exactly I make it all work.

I refrained from including these details on the original post because they're subject to immiment obsoletion. These tools are changing and evolving quickly, and some of these instructions are likely to become outdated in the coming months or even weeks.

The main tool

When evaluating the available transpilers, I decided to use 6to5, which has recently been renamed to Babel. I chose it based on:

  • No global object pollution
  • Source maps support
  • Not being opinionated about polyfills.

The last point is definitely important to me. I pay special attention to the resulting build size, specially when targeting browsers. The ability to choose any polyfill I want pays off.

I use Babel in several ways:

0. Hacking ES6 around

If you just want a ES6 REPL:

npm install -g babel
babel-node

will show something like:

Note: if you want to record GIFs like that directly from the terminal, look into my utilty clif.

I also set up an alias es:

alias es=babel-node

to easily run any file with this wrapper around Node:

echo "console.log(\`Node version: \${process.version}\`);" > /tmp/template-strings.js
es /tmp/template-strings.js

1. Writing ES6 Modules

Start with including babel in your package.json:

npm install babel --save

Notice I didn't use --save-dev. Since you might need polyfills, you probably are better off saving Babel as a regular dependency.

It's possible to make ES6 compilation work like CoffeeScript. If you include:

require('babel/register');

Subsequent require calls will be on-the-fly compiled. I refrain from doing this because of the runtime execution penalty. I want my ES6 code to run just as fast as my regular code[1].

I set up a Makefile task that creates node/ directory with my build:

BABEL = ./node_modules/.bin/babel

all: node

node: lib
  @mkdir -p node/
  @for path in lib/*.js; do \
    file=`basename $$path`; \
    $(BABEL) "lib/$$file" > "node/$$file"; \
  done

and I run this prior to publishing on NPM. My package.json main points to node/index:

{
  "main": "./node/index",
}

My .gitignore includes node and my .npmignore includes lib.

At this point you might be concerned about re-running the build and watching directories. Thankfully, this is not a problem at all for me because I mostly run my code by triggering tests.

2. Writing ES6 tests

Making mocha work with ES6 is as easy as creating a file called mocha.opts inside your test/ directory with the following contents:

--require babel/register

This means that you should assume code will be compiled when require is run, like I mentioned above.

When you include your module from the tests, make sure to point to the source (lib/) instead of the compiled version (node/):

import myModule from '../lib';
describe('my tests', () => {
  it('is shorter than ES5!', done => {
    setTimeout(done, 500);
  });
});

3. Writing ES6 browser modules

If you use browserify, it's as simple as including the babelify transform:

npm install babelify --save-dev
browserify -t babelify client/index.js -o public/build.js

[1] There's still a performance penalty with full spec compliance. Look into loose mode and benchmark whenever necessary.

@steida
Copy link

steida commented Feb 23, 2015

I highly recoment Webpack instead of Browserify. It's pain to setup, but it's worth it. I will release new Este this week, you will see magic (mostly inspired from Om :-) As for ES6, Lint is almost done eslint/js#10. Flowtype is approaching as well. For unit testing, did you try Jest?

@rauchg
Copy link
Author

rauchg commented Feb 24, 2015

@steida definitely should add webpack / espree instructions. Feel free to send me a patch for this doc.

@gr0uch
Copy link

gr0uch commented Feb 24, 2015

@rauchg why not use the babel-runtime package? It is intended for distribution and with this way you don't have global pollution nor dependency on babel.

@kristianmandrup
Copy link

Any of you guys have updated instructions for using this with Webpack or whatever better tech has come along since then Any skeleton project or yo generator you can recommend to get up and running?
Cheers!

@kristianmandrup
Copy link

How do I setup a project for node with Babel 5, ESLint and support for Stage 0 as outlined in:
http://babeljs.io/docs/usage/experimental/

Any good project templates out there preconfigured for this?

Thanks :)

@mauriciopoppe
Copy link

Babel has now this builtIn

// package.json
{
  "node": "babel lib --out-dir node"
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment