Babel, or, "I just want to use ES6"

So something that I've found endlessly irritating in recent months is Javascript, and in particular the different flavours of same. An awful lot of demo code is being written in 'ES6' but there's a lot of instances — particularly front-end in a browser — where ES6 code just immediately fails.

ES6, short for ECMAScript 6, also known as ECMAScript 2015, is (nearly) the latest version of Javascript; ECMAScript is the 'official' name of the language commonly known as Javascript. The previous 'stable' version of Javascript, which is pretty much guaranteed to run everywhere, is ES5.

The solution, I kept hearing, was to use a package called Babel — but there seems to be very little instruction on installing just Babel, without also being dragged down the path of linters and module bundlers and other stuff that I don't (yet) understand. All I want is to be able to write code in ES6 in a text editor and automatically convert it to ES5 so it'll work in all browsers!

The rest of this post is in the form of a short tutorial for those who want to follow along. It 'only' gets Babel working at the most basic level — I'm aware there's a lot more that can be done, and other packages that can be combined with Babel, but that's all for another day.

Getting started with Babel

I used Cloud9 as a development environment, which has one major benefit — there's absolutely no way to mess up your own computer if you're making all the changes in a virtual dev environment! If you're following along, I strong recommend doing so on Cloud9.

If you don't already have an account, Cloud9 is a fantastic service; you can create virtual workspaces, all running on Ubuntu Linux, and have them accessible from any web browser — and the basic service is free.

Update, December 2020 — Cloud9 was purchased by Amazon a few years ago, and the old service has now been shut down. You can still deploy a Cloud9 instance on AWS, quite cheaply, but it's no longer available for free. If you go the AWS route you'll have a complete Cloud9 install including npm ...

To ensure a proper learning experience, so that we're doing all the work ourselves, we're going to start with a new workspace and use the 'blank' template.


Do we have NPM?

The first we need to do is see whether NPM (Node Package Manager) is installed, because we're going to need it! Use the command

npm --version

in the terminal to check - if you get a version number back then NPM is installed, otherwise you're going to want to run

sudo apt-get install nodejs

from the terminal.


Great, so now let's get Babel

Before actually installing Babel, let's make a new folder for our project. From the command line type these two commands:

mkdir babel-trial
cd babel-trial

The mkdir command makes a new folder ('directory') and the cd command changes directory so that your terminal is in the project folder.

Next we need to initiate NPM, so run

npm init

in the terminal. You'll be given a number of options in order to create the package.json file, feel free to 'enter' through them to accept the defaults (most can be deleted anyway!).

Now we can use NPM to install the Babel CLI (Command Line Interface) tools:

npm install --save-dev babel-cli

If you know much about Node and NPM, you might be thinking about using the --global tag here — but everything that I've found says don't.

Once NPM has finished installing babel-cli, your package.json contents should look like this (I've deleted some of the entries for legibility, they're not required so feel free to do the same)

{
  "name": "babel-trial",
  "version": "1.0.0",
  "devDependencies": {
    "babel-cli": "^6.24.1"
  }
}

Folders and some code

I want to keep my ES6 files separate to the compiles ES5 files, so I'm going to make two directories — 'ES6' and 'js', both at the root of my babel-trial directory. So (making sure that the terminal is at babel-trial) enter the following commands in the terminal:

mkdir ES6
mkdir js

I also want to have a short instruction for compiling all my ES6 files in the project at the same time, and we can do this by adding a script in the package.json file. Just add this entry (I suggest putting it below the "version" and above the "dependencies" (don't forget the comma after the closing curly brace):

  "scripts": {
    "build" : "babel ES6 -d js"
  },

That script means that we can use the terminal command npm run build to transpile our code (remember, we need to be sure that the terminal is in the project root directory before invoking that command.)

The command that we're using here is --out-dir, which we've shortened to -d; it takes a source directory and a target directory, and runs through all files within the source directory. To run just one file, we would instead use the --out-file command, which can be shortened to -o, which takes an input file and output file instead.


Giving it a go

So Babel is installed - now we need some ES6 code and then we can run a trial. Create a file test.js in the ES6 directory, and give it some ES6 code like the following:

var myArray = [0,1,2,3,4,5,6,7,8,9,10]

console.log(myArray.reduce((a,b) => a+b))

Now we can just run our terminal command

npm run build

and another version of test.js will be transpiled into the js directory, in good old ES5 code. We can check that it's been converted by opening the js/test.js file ...

... oh.

So, nope, it looks like that's not working. The js/test.js file has been created, but it's still got the same exact code as the ES6/test.js version. We've missed a step ...


The missing step

Turns out what we've not done is given Babel any instructions as to what we want it to do with the input code — so it's not making any changes. To solve this, the first thing that we need to do is create a .babelrc file, which will contain information for Babel about the presets and plugins that we want to use. To make the file we can use the touch command from the terminal (again, ensuring that we're in the project root directory):

touch .babelrc

And then edit the empty .babelrc file so that it looks like this:

{
  "presets": [],
  "plugins": []
}

To compile ES6 code to ES5, we need a preset — and adding it is a two-step process. First we have to install it using NPM, and then we need to edit the .babelrc file.

To install, run the command

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

in the terminal; once that's installed (and it may take a little time, don't panic!) we then need to edit the .babelrc file to use the preset that we've just installed:

{
  "presets": [
    "es2015"
  ],
  "plugins": []
}

And if we now try our terminal command again ...

npm run build

... hey presto, the transpiled code in js/test.js is now in ES5!

"use strict";

var myArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

console.log(myArray.reduce(function (a, b) {
  return a + b;
}));

And to enable writing ES6 code in the text editor on my laptop, I can follow the same steps. This isn't unlocking the real power of Babel, but it's definitely breaking the ice ...