Setting up ES6+Babel+Gulp

ECMAScript 6 (ES6, specification at http://www.ecma-international.org/ecma-262/6.0/) has many nice features, but presently not all browsers support ES6. However you can still develop your applications in ES6 and make it run in all browsers. For this you need what is called as transpiler – which converts ES6 code to ES5, which all browsers understand currently.

One of the popular transpiler is Babel . In this post we will see how to use Node.js (https://nodejs.org/), Gulp.js (https://gulpjs.com/), Browserify (http://browserify.org/)  to compile ES6 code to ES5.

Gulp is a build tool for Node.js applications. Browserify resovles ‘require’ modules of Node.js and bundles all modules in one file. We will first use browserify to combine all our JS code in one file and then feed the output to babelify to translate the code to ES5. Structure of this sample project is as follows –

ES6BabelTest
  -- build
  -- src
    -- js
    -- html
  -- gulpfile.js

Not all the files are folders are shown above, for example package.json and node_modules folder are not shown.

Let’s first write some simple ES6 code. We will create a Person class (person.js) , instantiate that in index.js and we will include index.js in index.html which we will create in src/html folder.

person.js :

export default class Person {
    constructor (firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    getFirstName() {
        return this.firstName;
    }

    getLastName() {
        return this.lastName;
    }
}

index.js:

import Person from "./person";

let person = new Person("Ram", "Kulkarni");

document.getElementById("nameSpan").innerHTML = person.getFirstName() + " " + person.getLastName();

And index.html is :

<!DOCTYLE html>

<html>
    <head>
        <title>Babel Test</title>
    </head>
    <body>
        <h2>Testing ES6 + Babel</h2>
        <b>Name :</b> <span id="nameSpan"></span>
        <script src="bundle.js"></script>
    </body>
</html>

Note that in the above code bundle.js would be generated as an output of a Gulp task.

Before we take a look at guplfile.js, make sure required npm modules are installed. You should have installed gulp globally and also add it in dev dependencies (so that it is added to packages.json). Run following command to do this (it is assumed here that you have installed node.js) –

npm install -g --save-dev gulp

Then install following modules –

npm install --save-dev babel-core babel-loader babelify browserify gulp-connect vinyl-source-stream

Let’s now look at guplfile.js

//Include required modules
var gulp = require("gulp"),
    babelify = require('babelify'),
    browserify = require("browserify"),
    connect = require("gulp-connect"),
    source = require("vinyl-source-stream")
;

//Default task. This will be run when no task is passed in arguments to gulp
gulp.task("default",["copyStaticFiles", "build", "startServer"]);

//Copy static files from html folder to build folder
gulp.task("copyStaticFiles", function(){
    return gulp.src("./src/html/*.*")
    .pipe(gulp.dest("./build"));
});

//Convert ES6 ode in all js files in src/js folder and copy to 
//build folder as bundle.js
gulp.task("build", function(){
    return browserify({
        entries: ["./src/js/index.js"]
    })
    .transform(babelify)
    .bundle()
    .pipe(source("bundle.js"))
    .pipe(gulp.dest("./build"))
    ;
});

//Start a test server with doc root at build folder and 
//listening to 9001 port. Home page = http://localhost:9001
gulp.task("startServer", function(){
    connect.server({
        root : "./build",
        livereload : true,
        port : 9001
    });
});

Now run gulp command in the project folder, to execute the default task. However that results in the following error –

events.js:72
        throw er; // Unhandled 'error' event
              ^
SyntaxError: 'import' and 'export' may appear only with 'sourceType: module'

It turns out that earlier Babel was shipping with all the required plugin, including one that transaltes ES6 to ES5. But since Babel 6.0, you have to explicitly include plugins or presets (which include certain predefined plugins). So we will install Babel preset es2015 . Execute following command –

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

But this is not enough. We need to add this present in the Babel configuration. We could do that by passing configuration parameter to babelify –

gulp.task("build", function(){
    return browserify({
        entries: ["./src/js/index.js"]
    })
    .transform(babelify.configure({
        presets : ["es2015"]
    }))
    .bundle()
    .pipe(source("bundle.js"))
    .pipe(gulp.dest("./build"))
    ;
});

After this change, gulp executes without any error and ES6 is translated by Babel to ES5. Browse to http://localhost:9001 and verify that the application works.

-Ram Kulkarni

Leave a Reply