6to5-2

Escribiendo módulos de ES6 con 6to5

«El futuro llegó hace rato todo un palo, ya lo ves.»

Carlos Solari – Todo un palo

Como buenos nerds estamos constantemente detrás del desarrollo de nuevas tecnologías y de la evolución de aquellas que nos interesan. Es por eso que la discusión e implementación de aspectos del estándar de EcmaScript nos encuentra siempre atentos y con ganas de experimentar.

Por lo general en la vida del JavaScript en el cliente se suele mirar todo el tiempo la compatibilidad para atras. Así es como Can I use es frecuentado diariamente por nosotros. Mirar para adelante es motivo de exaltación.
El problema principal está en separar las nuevas herramientas que resultan útiles de aquellas que se nos aparecen simplemente por una cuestión de moda o marketing.

Luego de una JSConfAR plagada de charlas sobre ES6 decidí investigar la viabilidad técnica y los potenciales beneficios de agregar un transpiler de ES6 a ES5 (el compromiso de compatibilidad del panel de administración de Mango es de IE8+ y navegadores modernos).

6to5

La búsqueda fue fructífera y me llevó a 6to5. El slogan es claro: «Next generation JavaScript, today». La idea es simple y poderosa, muchas de las características de los nuevos estándares pueden convertirse con la ayuda de transformaciones a una sintaxis compatible con ES5, posibilitando correr el código en por ejemplo versiones antiguas de Internet Explorer. El sitio de 6to5 cuenta con un REPL que permite jugar y fanatizarse rápidamente.

La inclusión de 6to5 a nuestro build system fue literalmente de 2 lineas. El equipo de 6to5 también mantiene 6to5ify, un plugin de Browserify, del cual hablamos en un post anterior, que analiza el código ES6 compatible y lo convierte a ES5. Un punto a destacar es que la inclusión de 6to5 no involucró la modificación de ni una linea de código del producto. El código escrito no necesita ser modificado (no hay excusas).

Usando el CLI de Browserify, se puede correr 6to5ify del siguiente modo:

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

Para soportar algunas características en el navegador se necesitan incluir polyfills que vienen incluidos en 6to5. La inclusión de los polyfills estuvo a un `require(‘6to5/polyfill’)` de nuestros ambiente de desarrollo.

Ya lo estamos usando y está más lindo que nunca

Durante la primera semana de uso de 6to5 en el día a día usamos muchas features de ES6 en nuestro código.

Sin explicar sus funciones detalladamente, paso a detallar el uso que le estamos dando a algunas de ellas:

Arrow functions

Esta construcción es fundamental para un lenguaje y una plataforma (la web) que delega tanto peso en los callbacks. Las arrow functions no son solo un shortcut para definir funciones sino que tienen una característica super útil como es el lexical binding. Gracias a las arrow functions nos olvidamos casi por completo del clásico `self = this`. Este ejemplo es del primer commit que usa ES6 en nuestro código.

Antes:

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

Después:

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

 

Classes

En nuestros módulos es muy común encontrar el siguiente patrón

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

La sintaxis de clases de ES6 manifiesta este patrón de un modo claro

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

 

let + const

Como se suele decir `let` es el nuevo `var`, pero con Block scoping. Es interesante que salvo los casos donde el scope de bloque cobra valor, el transpiler pasa las declaraciones de `let` directamente a var.

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;
}

Respecto al agregado de constantes mediante la keyword `const` recuerdo a un compañero de trabajo que venía de Java y me preguntaba si no me gustaba declarar constantes o si era una falla de diseño del lenguaje. Esta nueva keyword implica para 6to5 chequeos en tiempo de compilación. Si el análisis de código estático detecta una doble asignación, simplemente frena la compilación y nos advierte del error. Un uso que le estamos dando a `const` más allá del de declarar nuevas constantes es usarlo para los `require`. No queremos modificar los objetos que exportan otros módulos directamente. Usando `const` nos aseguramos de no equivocarnos.

const Input = require('input');

 

Parameter destructuring

Otro patrón común en nuestro código es un constructor que recibe una serie de opciones mediante un parámetro que es un objeto del siguiente modo:

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

usando ES6 podemos escribir:

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

 

Template Strings

El que nunca armó una url de esta manera que tire la primer piedra:

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

Los template strings lo hacen amigable:

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

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

 

Conclusiones

El uso de las features detalladas y algunas otras nos ayudan a ser más productivos y a la vez escribir código más entendible y menos propenso a errores. Decisiones de este tipo no solo hacen a la comodidad del programador sino que se traducen en mejoras de productividad para proyectos y empresas tanto a la hora de generar nuevas oportunidades como de mantener código previamente puesto en producción.

Esperamos seguir descubriendo caminos interesantes usando ES6 y contar como nos puede ayudar a mejorar la calidad del desarrollo web.

 

ES7: Mirando un poco más allá del horizonte

Una vez completado ES6 se empezó a debatir ES7. Así como 6to5 nos permite usar funcionalidades de ES6 antes de estar disponible en ciertos ambientes, lo mismo ocurre con ES7.

Es por eso que estamos en condiciones de hacer uso de las keywords async/await que hacen sentir la programación asíncrona como si estuviéramos escribiendo código sync o generator comprehensions que justamente permiten construir generadores por comprensión. Esta última se encuentra en modo experimental para 6to5.

Algunos recursos interesantes:

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

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