· ES6 CoffeeScript Compiler Build Tools

The Move from CoffeeScript to ES6

CoffeeScript, no more

The biggest source of pushback as we onboard new developers has been that our front-end code was written in CoffeeScript. There was a distinct lack of enthusiasm to read up and learn CoffeeScript, since the perception is that it’s a dead-end technology.

The Challenge: converting 20,000 lines of CoffeeScript to ES6

When we finally decided to port our CoffeeScript code to ES6, the actual task of going through the translation seemed like a herculean effort. We tried converting a script around a thousand lines long and that took about a day. That sample exploration included getting up to speed with ES6 and deciding what our Backbone code would look like. If we are to say that pace is about right, that means it would take about one man-month to convert the entire codebase. Beyond the time and pain that effort would take, we were also concerned about the quality of code produced if someone were to convert it all by hand.

We then thought that there must be a script that would translate CoffeeScript to ES6 code. While two projects claim they can do the deed, neither actually worked for us. So, we wrote our own.

Our CoffeeScript to ES6 transpiler

Luis Artola, one of our developers, took about a week converting the CoffeeScript compiler to generate ES6 code from CoffeeScript. You can find the code here: Unbrew.

We’re planning a followup post where Luis will go into the details on the different issues he came across when editing the transpiler and the overall effort involved.


How we came to our decision

CoffeeScript: the good parts

When we first introduced CoffeeScript into the Evite codebase back in 2012, we loved it. To that end, the team that first was involved with using CoffeeScript still loves CoffeeScript. Also, we know how much CoffeeScript has impacted the front-end world and ES6 specifically. At the time, it was the best, and now, it’s still great. We just have another option that has a lot going for it.

CoffeeScript: the bad parts

Implicit returns, moving on. (discussion here)

ES6, the sales pitch

A lot of the details that make CoffeeScript compelling worked their way into the ES6 spec. Also, a couple things that we got when including Underscore also come for free in ES6. Examples of things we like:

ES6: the not so pretty parts

ES6 in production: learnings

As mentioned earlier, we started with 20,000 lines of CoffeeScript code. When translated that resulted in approximately 50,000 lines of ES6 code.

During testing our QA team caught a semi-serious gotcha with Babel, the ES5 it renders does not work in most IE browsers. We then found this list of known issues. So we had to polyfill a couple things for IE (and a couple other) browsers. This is what we had to our base template files.

<script>
    if(window['Symbol'] === undefined ||
        window['Promise'] === undefined ||
        typeof Object.assign !== 'function') {
            document.write('<scr'+'ipt src="//cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.7.4/polyfill.min.js"></sc'+'ript>');
    }
</script>

How to transpile ES6 code

First install these Node packages:

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

Then run babel like so:

$ ./node_modules/.bin/babel <name of script> --presets es2015

Module support in the browser

We recently also turned on module support. It was fairly simple. All you have to do is turn on the CommonJS Babel plugin. And then run the code that generates through Browserify.

Install the following Node packages:

$ npm install babel-plugin-transform-es2015-modules-commonjs
$ npm install browserify

Our .babelrc file looks like this:

{
    "presets": ["es2015"],
    "plugins": [
        "transform-proto-to-assign",
            [
                "transform-es2015-classes", {
                    "loose": true
                },
                "transform-es2015-modules-commonjs", {
                    "allowTopLevelThis": false,
                    "strict": false,
                    "loose": false
                }
           ]
       ]
}

Then run the following commands

$ babel <path to ES6 file>.es6 --out-file <path to transpiled JS file>.js	
$ browserify <path to transpiled babel generated JS file>.js --outfile <path to Browserify JS file>.js

Conclusion

Converting all the code over was a serious undertaking. With that out of the way, playing with ES6 has been great. There are a lot of nice tools and libraries we can now play with. CoffeeScript – for the most part – is a more elegant, more concise language, but ES6 is a bit more explicit. Having played in both lands, explicit seems to be more important when working on a project at our scale. There was nuance to what CoffeeScript was doing that became more obviuos after we converted to ES6.

Resources:

CoffeeScript at Evite (b. 9/27/2012 d. 5/4/2016)

By Michael Irani