6to5-2

Writing ES6 modules with 6to5

Next Saturday night, we’re sending you back to the future!

– Dr. Emmett L. Brown, Back to the Future (1985)

Like the nerds we are, we constantly check new technologies and the evolution of the ones we’re already interested in. That’s why the discussion of the implementation of different aspects of the EcmaScript standard keeps us interested and gives us the motivation to experiment new things.

Backwards compatibility is always important on the client-side JavaScript development process. That’s one reason why Can I use is one of the tools we use almost everyday. Looking forward is always exciting.
The problem with this is knowing which tools are going to be really useful from the ones that are just a fad.

After a JSConfAR filled with talks about ES6, I decided to investigate the possibility of adding a ES6 to ES5 transpiler and its potential benefits. Our aim included that Mango’s Dashboard browser compatibility included IE8+ and modern browsers.

6to5

The search was successful and led me to 6to5. The slogan says it all: «Next generation JavaScript, today». The idea is simple and powerful, a lot of the features of the new standards can be converted with the help of transformers, to a ES5 compatible syntax, making possible to run your code in older versions of Internet Explorer, for example. The 6to5 website has a REPL that allows you to experiment and easily become a fan of it.

The implementation of 6to5 to our build was done literally with 2 lines. The 6to5 also maintains 6to5ify, a Browserify plugin (something we talked about in a previous post), that analyses the ES6 compatible code and turns it into ES5. Something important to point out is that the implementation of 6to5 didn’t involve modifying not even one line of code from our product. The code doesn’t need to be modified at all.

Using the Browserify CLI, you can run 6to5ify in the following way:

$ browserify script.js -t 6to5ify --outfile bundle.js

In order to support some features on the browser, you should include polyfills already present in 6to5. In order to do that in our development environment, we only needed to add this: `require(‘6to5/polyfill’)`.

Better than ever

During the first week of using 6to5 we used a lot of ES6 features in our code daily.

Without going into detail, here are some of the ones we’re using right now:

Arrow functions

This construction is fundamental for a language and a platform (the web) that depends so much on callbacks. The arrow functions are not only a shortcut to define functions, but also have a very useful feature such as lexical binding. Thanks to arrow functions we can almost forget about the classic `self = this`. Look to the following example, of the first commit that uses ES6 in our code:

Before:

Tabs.prototype.show = function() {
  var self = this;
  // ...
  this.$triggers.on('click', function(eve) {
    self.select(target.getAttribute('data-tabs-trigger'));
    });
  }

After:

  Tabs.prototype.show = function() {
    // ...
    this.$triggers.on('click', (eve) => this.select(target.getAttribute('data-tabs-trigger'));
  }

 

Classes

In our modules, it’s very common to find the following pattern:

function Input(options) { // code }
inherit(Input, Emitter); // Input prototype inherits from Emitter
Input.prototype.val = function() {} // Extend prototype

The classes syntax in ES6 manifest this patter much more clearly:

class Input extends Emitter {
  constructor() { //code }
  val() { //... }
}

 

let + const

As its said `let` is the new `var`, but with Block scoping. It’s interesting that in exception of the cases where the block scope became relevant the transpiler converts `let` statements into var’s.

let a = 3; // written code
var a = 3; // transpiled code (in most contexts)

// written code
let x = 2;
{
  let x = 3; // new var different than above
}

// Transpiled code
var x = 2;
{
  var _x = 3;
}

Regarding adding constants using the keyword `const`, I remember a colleague that worked with Java who used to ask me if I didn’t like to declare constants or if there was a problem with the language design. This new keyword implies for 6to5 making checks at compilation time. If the static code analysis detects a double assign, it simply stops the compilation process and prompts the error. One of the uses that we’re assigning to `const` besides declaring new constants, is using it for the `require`. We don’t want to modify the objects that export other modules directly. Using `const`, we make sure we didn’t make a mistake.

const Input = require('input');

 

Parameter destructuring

Another pattern in our code is a constructor that receives a series of options via a parameter that is an object in the following way:

function Form(options) {
  options = options || {};
  this.size = options.size;
  this.legend = options.legend;
}

using ES6 we could write:

function Form({size, legend}={}) {
  this.size = size;
  this.legend = legend;
}

 

Template Strings

Anyone who hasn’t created a URL in the following way, throw the first stone.

function fetchData(id) {
  request('/api/controller/' + id + '/action/');
}

Template strings make this more friendly:

// Written code
function fetchData(id) {
  request('/api/controller/${id}/action/');
}

// Transpiled code
function fetchData(id) {
  request('/api/controller/' + id + '/action/');
}

 

Conclusions

The use of the features above and some others, helps us to be more productive and also to write more friendly code and less error-prone. Making the decision to code this way is not just about the comfort of the developers, but also impacts on productivity for projects where there’s need to maintain code already in production.

We hope to continue discovering interesting paths using ES6 and letting you know about how it can help us to enhance the quality of the web development.

 

ES7: Looking beyond the horizon

Once ES6 was completed, the discussion about ES7 started. Just like 6to5 allows us to use ES6 features before it’s available in some environments, the same happens with ES7.

That’s why we are in conditions to make use of such keywords as `async` and `await`that allows async programming a lot like sync, or event use generator comprehensions. The latter is available as an `experimental feature` for 6to5.

More resources:

ES6 Rocks
Understanding ES6
Axel Rauschmayer Blog
6to5 Tour
ES6 Overview

Los comentarios están cerrados para este artículo.