5.0.0 Lanzado
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
En los últimos meses, Babel ha sido adoptado por varias comunidades importantes como Node, React, Ember, Backbone, Angular, Rails y muchas otras. Lanzamos la página de Usuarios hace apenas unas semanas y es fascinante ver todos los que lo están utilizando. Empresas como CloudFlare, Netflix, Mozilla y Yahoo!. Proyectos como Ghost, Atom, Mapbox y muchos más.
Hemos visto innumerables publicaciones de blog, charlas, eventos y cursos sobre ES6+ usando Babel, y las herramientas oficiales de Babel se han descargado casi 2 millones de veces.
Hoy realizamos el lanzamiento más grande de Babel hasta la fecha.
Si estás actualizando desde Babel 4.x, consulta los cambios importantes.
Esta versión incluye las nuevas propuestas para ES7:
Toda la tubería interna de recorrido y transformación ha sido reescrita, lo que aumenta sustancialmente la flexibilidad y permitirá futuras optimizaciones de rendimiento en el pipeline.
Esta versión también introduce una API de plugins, que permite a los usuarios conectar sus propios transformadores personalizados para aprovechar los poderosos mecanismos de transformación que ofrece Babel.
Puedes ver el CHANGELOG completo aquí.
Y como siempre, si encuentras algún problema de regresión, repórtalo inmediatamente.
Proceso TC39
En esta versión comenzarás a vernos alineados con el proceso TC39. TC39 es el comité técnico de ECMA que escribe el estándar ECMAScript. Su proceso se divide en 5 etapas:
-
Etapa 0 - Strawman
-
Etapa 1 - Propuesta
-
Etapa 2 - Borrador
-
Etapa 3 - Candidato
-
Etapa 4 - Finalizado
Las propuestas en etapa 2 o superior están habilitadas en Babel por defecto. Esto no significa que estén garantizadas para incluirse en futuras especificaciones de ECMAScript o incluso en el propio Babel. La etapa 2 se considera un buen punto para la inclusión predeterminada en Babel debido a su relativa madurez y la necesidad de retroalimentación crítica sobre las propuestas.
Ahora profundicemos en los cambios que implementamos en la versión 5.0.
Contenidos:
New Features
Nuevas propuestas
Etapa 0: Propiedades de clase (Class Properties)
La propuesta de inicializadores de propiedades de clase en etapa 0 de Jeff Morrison soluciona la falta de composición de propiedades en clases. Son análogas al ejemplo de propiedades de clase mencionado en el anuncio de React 0.13 beta.
Ejemplo:
class Person {
firstName = "Sebastian";
static lastName = "McKenzie";
}
assert(new Person().firstName, "Sebastian");
assert(Person.lastName, "McKenzie");
Uso:
require("babel").transform("code", {
optional: ["es7.classProperties"]
});
// or
require("babel").transform("code", { stage: 0 });
$ babel --optional es7.classProperties script.js
# or
$ babel --stage 0 script.js
Etapa 1: Decoradores (Decorators)
La propuesta de decoradores en etapa 1 de Yehuda Katz permite componer elegantemente descriptores de propiedad y decoración de metadatos. En el futuro esto facilitará representar el potente Modelo de Objetos de Ember con clases nativas.
Ejemplo:
function concat(...args) {
let sep = args.pop();
return function(target, key, descriptor) {
descriptor.initializer = function() {
return args.map(arg => this[arg]).join(sep);
}
}
}
function autobind(target, key, descriptor) {
var fn = descriptor.value;
delete descriptor.value;
delete descriptor.writable;
descriptor.get = function () {
var bound = fn.bind(this);
Object.defineProperty(this, key, {
configurable: true,
writable: true,
value: bound
});
return bound;
};
}
class Person {
firstName = "Sebastian";
lastName = "McKenzie";
@concat("firstName", "lastName", " ") fullName;
@concat("lastName", "firstName", ", ") formalName;
@autobind
getFullName() {
return `${this.firstName} ${this.lastName}`;
}
}
assert(new Person().fullName, "Sebastian McKenzie");
assert(new Person().formalName, "McKenzie, Sebastian");
assert(new Person().getFullName.call(null), "Sebastian McKenzie");
Uso:
require("babel").transform("code", {
optional: ["es7.decorators"]
});
// or
require("babel").transform("code", { stage: 1 });
$ babel --optional es7.decorators script.js
# or
$ babel --stage 1 script.js
Etapa 1: Extensiones de exportación (Export Extensions)
La propuesta de declaraciones adicionales export-from en etapa 1 de Lee Byron completa la simetría entre import y export, permitiendo exportar fácilmente namespaces y defaults desde módulos externos sin modificar el ámbito local.
Exportar un default
export foo from "bar";
equivalente a:
import _foo from "bar";
export { _foo as foo };
Exportar un namespace
export * as ns from "mod";
equivalente a:
import * as _ns from "mod";
export { _ns as ns };
Uso:
require("babel").transform("code", {
optional: ["es7.exportExtensions"]
});
// or
require("babel").transform("code", { stage: 1 });
$ babel --optional es7.exportExtensions script.js
# or
$ babel --stage 1 script.js
Optimizaciones para React
Como preparación para React 0.14, Babel incluye transformadores de optimización para JSX.
Elementos constantes
A partir de la versión 0.14, los ReactElements y sus objetos de props pueden tratarse como tipos de valor. Es decir, cualquier instancia es conceptualmente equivalente si todos sus valores son idénticos.
Tomemos esta función como ejemplo:
import React from "react";
function render() {
return <div className="foo" />;
}
Puede optimizarse moviendo el JSX fuera del cuerpo de la función para que cada llamada devuelva la misma instancia:
import React from "react";
var _ref = <div className="foo" />;
function render() {
return _ref;
}
Además de permitir reutilizar los mismos objetos, React omitirá automáticamente cualquier reconciliación de componentes constantes, sin necesidad de un shouldComponentUpdate manual.
Uso:
require("babel").transform("code", {
optional: ["optimisation.react.constantElements"]
});
$ babel --optional optimisation.react.constantElements script.js
Elementos en línea
Los elementos en línea deben habilitarse only en producción, ya que suprimen múltiples mensajes de advertencia de React, lo cual es muy riesgoso durante el desarrollo.
A partir de React 0.14, los ReactElements pueden insertarse en línea:
<div className="foo">{bar}<Baz key="baz" /></div>
como objetos:
{ type: 'div', props: { className: 'foo', children:
[ bar, { type: Baz, props: { }, key: 'baz', ref: null } ]
}, key: null, ref: null }
Esto mejora el rendimiento sobre la llamada existente React.createElement al insertar directamente su resultado.
Uso:
require("babel").transform("code", {
optional: ["optimisation.react.inlineElements"]
});
$ babel --optional optimisation.react.inlineElements script.js
.babelrc
Babel 5.0.0 incluye soporte nativo para .babelrc en todas sus integraciones. Esto significa que funcionará con babel/register, babel-node y todos los plugins de sistemas de construcción y loaders de módulos como babel-loader, babelify, entre otros.
.babelrc es equivalente a .jshintrc de JSHint y .jscsrc de JSCS.
{
"stage": 1,
"ignore": [
"foo.js",
"bar/**/*.js"
]
}
Consulta la documentación para más información.
API de Plugins
La versión 5.0.0 también introduce la tan esperada API de plugins. Esto te permite integrarte con los potentes mecanismos internos de recorrido y transformación de Babel. Consulta la documentación para más detalles.
Breaking Changes
Opción Experimental Eliminada
La opción experimental ha sido eliminada. Pero no te preocupes, hay un reemplazo. Babel ahora categoriza los transformadores de ES7 según las etapas TC39.
Resumen: Si usabas la opción experimental, simplemente cámbiala a $ babel --stage 0 o { stage: 0 }.
Recordatorio: Las propuestas en etapa 2 o superior están activadas por defecto.
Etapa 0
-
es7.classProperties -
es7.comprehensions
Etapa 1
-
es7.asyncFunctions -
es7.decorators -
es7.exportExtensions -
es7.objectRestSpread
Etapa 2 (Activadas por defecto)
es7.exponentiationOperator
Para ver todas las propuestas actuales de ES7, consulta el repositorio tc39/ecma262.
Cambio en la opción returnUsedHelpers
La opción returnUsedHelpers ha sido renombrada a metadataUsedHelpers, y el resultado devuelto ahora es metadata.usedHelpers en lugar de usedHelpers.
Cambios en Clases
La versión 5.0.0 introduce actualizaciones en la semántica de clases derivadas que eran necesarias.
En constructores de clases derivadas debe llamarse a super().
class Foo extends Bar {
constructor() {
// no `super();`
}
}
El acceso a this antes de super() en constructores de clases derivadas no está permitido.
class Foo extends Bar {
constructor() {
this.foo; // `this` access before `super();`
super();
}
}
super() solo se permite en constructores de clases derivadas.
class Foo {
constructor() {
super(); // not in a derived constructor
}
}
Características Eliminadas
-
Se ha eliminado el playground para enfocar el desarrollo en características ES estándar y propuestas. Esto también reduce el riesgo de conflictos sintácticos que impidan implementar características oficiales.
-
Las referencias abstractas se han eliminado porque la propuesta fue reemplazada. En el futuro podrían implementarse propuestas sustitutas.
Para finalizar, esperamos que esta versión os entusiasme tanto como a nosotros. Hay mucho trabajo detrás, y creemos que sienta las bases para el futuro.
— The Babel team
Los imports ahora se elevan (hoisted)
En la versión 4.x, los imports se insertaban donde aparecían en el código. Esto significa que este código:
global.test = 'test'
import './test'
se compilaría como:
'use strict';
global.test = 'test';
require('./test');
Sin embargo, a partir de 5.x, este comportamiento ha cambiado para cumplir con la especificación ES6 y las importaciones serán hoisted ahora. Esto significa que en código práctico el fragmento anterior se convertirá en algo como:
'use strict';
require('./test');
global.test = 'test';
Si tu código requería que ciertas operaciones se ejecutaran durante la importación de un módulo específico -como podría ocurrir al probar código donde necesitas simular propiedades de window :)- quizá quieras extraer ese comportamiento a un archivo separado e importarlo antes del código que lo necesita.