Rilasciata la versione 5.0.0
Questa pagina è stata tradotta da PageTurner AI (beta). Non ufficialmente approvata dal progetto. Hai trovato un errore? Segnala problema →
Negli ultimi mesi Babel è stato accolto in diverse grandi community come Node, React, Ember, Backbone, Angular, Rails e molte altre. Abbiamo lanciato la pagina Utenti solo poche settimane fa ed è fantastico vedere tutti coloro che lo stanno utilizzando. Aziende come CloudFlare, Netflix, Mozilla e Yahoo!. Progetti come Ghost, Atom, Mapbox e molti altri ancora.
Abbiamo visto tantissimi post di blog, talk, eventi e corsi incentrati su ES6+ con Babel, e gli strumenti ufficiali di Babel sono stati scaricati quasi 2 milioni di volte.
Oggi rilasciamo di gran lunga la versione più importante di Babel di sempre.
Se stai effettuando l'aggiornamento da Babel 4.x consulta le modifiche incompatibili.
Questa release include le nuove proposte per ES7:
L'intera pipeline interna di attraversamento e trasformazione è stata riscritta, migliorando sostanzialmente la flessibilità e consentendo future ottimizzazioni delle prestazioni.
Questa release introduce anche un'API per i plugin, che permette agli utenti di integrare trasformatori personalizzati per sfruttare i potenti meccanismi di trasformazione offerti da Babel.
Puoi consultare il CHANGELOG completo qui.
E come al solito se riscontri regressioni segnalale immediatamente.
Processo TC39
In questa release inizierai a vederci allineati al processo TC39. Il TC39 è il comitato tecnico di ECMA che redige lo standard ECMAScript. Il loro processo è suddiviso in 5 fasi:
-
Stage 0 - Bozza iniziale
-
Stage 1 - Proposta
-
Stage 2 - Bozza
-
Stage 3 - Candidato
-
Stage 4 - Concluso
Le proposte di stage 2 o superiore sono abilitate in Babel per impostazione predefinita. Ciò non significa che siano garantite per l'inclusione nelle future specifiche ECMAScript o nello stesso Babel. Lo stage 2 è considerato un buon punto per l'inclusione predefinita in Babel grazie alla relativa maturità e alla necessità di feedback critici sulle proposte.
Ora approfondiamo i cambiamenti apportati nella 5.0.
Indice:
New Features
Nuove Proposte
Stage 0: Proprietà delle Classi
La proposta di stage 0 sugli inizializzatori delle proprietà delle classi di Jeff Morrison colma la lacuna della composizione delle proprietà nelle classi. Queste sono analoghe agli esempi di proprietà delle classi elencati nell'annuncio beta di React 0.13.
Esempio:
class Person {
firstName = "Sebastian";
static lastName = "McKenzie";
}
assert(new Person().firstName, "Sebastian");
assert(Person.lastName, "McKenzie");
Utilizzo:
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
Stage 1: Decoratori
La proposta di stage 1 sui decoratori di Yehuda Katz consente di comporre elegantemente descrittori di proprietà e decoratori di metadati. In futuro ciò permetterà di rappresentare facilmente il potente Ember Object Model con classi native.
Esempio:
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");
Utilizzo:
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
Stage 1: Estensioni di Export
La proposta di stage 1 sulle istruzioni aggiuntive di export-from di Lee Byron completa la simmetria tra le istruzioni import ed export, consentendo di esportare facilmente namespace e default da moduli esterni senza modificare l'ambito locale.
Esportare un default
export foo from "bar";
equivalente a:
import _foo from "bar";
export { _foo as foo };
Esportare un namespace
export * as ns from "mod";
equivalente a:
import * as _ns from "mod";
export { _ns as ns };
Utilizzo:
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
Ottimizzazioni per React
In preparazione per React 0.14, Babel supporta alcuni trasformatori di ottimizzazione per JSX.
Elementi Costanti
A partire dalla versione 0.14, gli ReactElement e i loro oggetti props possono essere trattati come tipi di valore, cioè qualsiasi istanza è concettualmente equivalente se tutti i loro valori sono identici.
Prendiamo ad esempio questa funzione:
import React from "react";
function render() {
return <div className="foo" />;
}
Questo può essere ottimizzato spostando il JSX fuori dal corpo della funzione in modo che ogni volta che viene chiamata, venga restituita la stessa istanza:
import React from "react";
var _ref = <div className="foo" />;
function render() {
return _ref;
}
Non solo ci permette di riutilizzare gli stessi oggetti, ma React interromperà automaticamente qualsiasi riconciliazione di componenti costanti - senza un shouldComponentUpdate manuale.
Utilizzo:
require("babel").transform("code", {
optional: ["optimisation.react.constantElements"]
});
$ babel --optional optimisation.react.constantElements script.js
Elementi Inline
Gli elementi inline dovrebbero essere abilitati only in produzione poiché vengono soppressi messaggi di warning di React, il che è estremamente rischioso in sviluppo.
A partire da React 0.14, gli ReactElement possono essere inlinati:
<div className="foo">{bar}<Baz key="baz" /></div>
come oggetti:
{ type: 'div', props: { className: 'foo', children:
[ bar, { type: Baz, props: { }, key: 'baz', ref: null } ]
}, key: null, ref: null }
Questo migliora le prestazioni rispetto alla chiamata React.createElement esistente inlinandone il risultato.
Utilizzo:
require("babel").transform("code", {
optional: ["optimisation.react.inlineElements"]
});
$ babel --optional optimisation.react.inlineElements script.js
.babelrc
Babel 5.0.0 offre supporto nativo per .babelrc in tutte le sue integrazioni. Ciò significa che funzionerà con
babel/register,
babel-node e con tutta la gamma di plugin per sistemi di build e module loader come
babel-loader,
babelify, e altri.
.babelrc è l'equivalente di .jshintrc per JSHint e
.jscsrc per JSCS.
{
"stage": 1,
"ignore": [
"foo.js",
"bar/**/*.js"
]
}
Consulta la documentazione per maggiori informazioni.
Plugin API
La versione 5.0.0 introduce anche l'attesa API per i plugin. Questo ti permette di integrare le potenti funzionalità interne di traversamento e trasformazione di Babel. Vedi la documentazione per maggiori dettagli.
Breaking Changes
Opzione Sperimentale Rimossa
L'opzione experimental è stata rimossa. Non temere però: esiste un sostituto. Babel ora categorizza i transformer ES7 per
stage TC39.
tl;dr Se stavi usando l'opzione experimental, sostituisci semplicemente con
$ babel --stage 0 o { stage: 0 }.
Promemoria: Le proposte di stage 2 o superiore sono abilitate di default.
Stage 0
-
es7.classProperties -
es7.comprehensions
Stage 1
-
es7.asyncFunctions -
es7.decorators -
es7.exportExtensions -
es7.objectRestSpread
Stage 2 (abilitati di default)
es7.exponentiationOperator
Per la lista completa delle proposte ES7 attuali, consulta il repository tc39/ecma262.
Opzione returnUsedHelpers rinominata
L'opzione returnUsedHelpers è stata rinominata in metadataUsedHelpers e il risultato restituito
è stato modificato da usedHelpers a metadata.usedHelpers.
Modifiche alle Classi
La versione 5.0.0 introduce alcune aggiornate semantiche per le classi derivate attese da tempo.
super() deve essere chiamato nel costruttore di una classe derivata.
class Foo extends Bar {
constructor() {
// no `super();`
}
}
L'accesso a this prima di super() nel costruttore di una classe derivata non è consentito.
class Foo extends Bar {
constructor() {
this.foo; // `this` access before `super();`
super();
}
}
super() è consentito solo nei costruttori delle classi derivate.
class Foo {
constructor() {
super(); // not in a derived constructor
}
}
Funzionalità Rimosse
-
Il playground è stato rimosso per concentrare lo sviluppo sulle funzionalità ES principali e sulle proposte. Ciò riduce anche il rischio di conflitti sintattici che potrebbero impedire l'implementazione di funzionalità ufficiali.
-
I riferimenti astratti sono stati rimossi poiché la proposta è stata sostituita. Il supporto per una o più delle proposte sostitutive potrebbe essere implementato in futuro.
In conclusione, speriamo che tu sia entusiasta di questo rilascio quanto noi. C'è molto lavoro dietro, e crediamo che ci preparerà al meglio per il futuro.
— The Babel team
Gli import sono ora hoisted
Nella versione 4.x, gli import venivano inseriti inline dove comparivano nel codice. Ciò significa che questo codice:
global.test = 'test'
import './test'
verrebbe compilato in:
'use strict';
global.test = 'test';
require('./test');
Tuttavia, a partire dalla versione 5.x, questo comportamento è stato modificato per conformarsi alla specifica ES6 e le importazioni saranno ora hoistate. Ciò significa che nel codice pratico lo snippet sopra verrà convertito in qualcosa come:
'use strict';
require('./test');
global.test = 'test';
Se il tuo codice richiedeva che determinati elementi venissero eseguiti durante l'importazione di un modulo specifico -come potrebbe accadere durante il testing quando è necessario simulare proprietà di window :)- potresti estrarre quella logica in un file separato e importarlo prima del codice che ne necessita.