Vai al contenuto principale

In arrivo la versione 7.0

· Lettura di 16 min
Traduzione Beta Non Ufficiale

Questa pagina è stata tradotta da PageTurner AI (beta). Non ufficialmente approvata dal progetto. Hai trovato un errore? Segnala problema →

Consulta Planning for 7.0 per gli ultimi aggiornamenti delle pre-release 7.0. Se qualcosa in questo post non è chiaro, fatemelo sapere!

Aggiornamenti sul progetto

  • Abbiamo lanciato una nuova pagina video! L'abbiamo creata per chi vuole approfondire il funzionamento di Babel e aiutare altri a contribuire. Questa pagina raccoglie talk conferenziali su Babel e concetti correlati, realizzati da membri del team e dalla community (puoi inviare una PR se hai tenuto un talk simile).

video

  • Abbiamo creato anche una nuova pagina del team! Aggiorneremo questa pagina in futuro con maggiori dettagli sui ruoli e le motivazioni dei membri. Per un progetto così ampio, ci sono molti modi per contribuire e dare supporto.

team

  • Babel ha compiuto 3 anni il 28 settembre 2017!

  • Daniel ha spostato babel/babylon e babel/babel-preset-env nel monorepo principale di Babel, babel/babel, inclusi tutta la cronologia git, le etichette e le issue.

  • Abbiamo ricevuto una donazione di $1.000/mese da Facebook Open Source!

    • È la donazione mensile più alta ricevuta finora (la seconda è di $100/mese).
    • Utilizzeremo i fondi per incontri in presenza e per partecipare alle riunioni TC39. Questi meeting si svolgono ogni 2 mesi in varie parti del mondo.
    • Se un'azienda vuole sponsorizzare attività specifiche, possiamo creare issue dedicate. In precedenza era difficile perché dovevamo pagare di tasca nostra o trovare conferenze coincidenti per coprire i costi.

Come puoi aiutare!

Se la tua azienda vuole restituire valore supportando un pilastro fondamentale dello sviluppo JavaScript e il suo futuro, valuta di donare al nostro Open Collective. Puoi anche donare tempo di sviluppo per aiutare a mantenere il progetto.

#1 Supporta la manutenzione del progetto (tempo sviluppatori durante l'orario lavorativo)

La risorsa più preziosa per questo progetto sono persone impegnate ad aiutare, data l'enorme mole di lavoro/responsabilità. Come ho già detto, non mi sentivo pronto a essere maintainer, ma ci sono capitato quasi per caso. Sono solo una persona e il nostro team è composto da poche unità.

#2 Finanzia lo sviluppo

Puntiamo decisamente a finanziare membri del team per lavorare a tempo pieno. Logan in particolare ha lasciato il lavoro tempo fa e sta usando i fondi attuali per contribuire a Babel part-time!

#3 Contribuisci in altri modi 😊

Ad esempio, Angus ci ha dedicato una canzone ufficiale!

Aggiornamento

Stiamo inoltre sviluppando uno strumento di aggiornamento che aiuterà a riscrivere i tuoi file package.json/.babelrc e altro ancora. Idealmente, ciò significa che modificherà eventuali cambiamenti necessari nei numeri di versione, rinomina i pacchetti e aggiorna la configurazione.

Segnala eventuali problemi durante l'aggiornamento e offri il tuo supporto! Questa è un'ottima opportunità per contribuire e aiutare l'ecosistema ad aggiornarsi!

Riepilogo del post precedente

  • Rimozione del supporto per Node 0.10/0.12/5.

  • Aggiornamento delle proposte TC39

    • Separatori numerici: 1_000
    • Operatore di navigazione sicura: a?.b
    • import.meta (analizzabile)
    • Binding opzionale per catch: try { a } catch {}
    • BigInt (analizzabile): 2n
    • Suddivisione delle estensioni di export in export-default-from e export-ns-form
  • Supporto per .babelrc.js (configurazione in JavaScript invece di JSON)

  • Aggiunto un nuovo preset TypeScript + separazione dei preset React/Flow

  • Rimossa la dipendenza interna babel-runtime per ridurre le dimensioni

Proposte TC39 aggiornate

  • Operatore pipeline: a |> b

  • Espressioni throw: () => throw 'hi'

  • Operatore di coalescenza null: a ?? b

Preset annuali deprecati (es. babel-preset-es20xx)

TL;DR: usa babel-preset-env.

Cosa c'è di meglio che dover decidere quale preset Babel usare? Farlo automaticamente al posto tuo!

Nonostante il lavoro enorme richiesto per mantenere gli elenchi di dati - ecco perché abbiamo bisogno di aiuto - risolve molteplici problemi: tiene gli utenti aggiornati con le specifiche, riduce la confusione su configurazioni/pacchetti, semplifica gli aggiornamenti e diminuisce i dubbi sulle funzionalità.

babel-preset-env è in realtà un preset piuttosto datato che sostituisce qualsiasi altro preset sintattico necessario (es2015, es2016, es2017, es20xx, latest, ecc...).

preset npm

Compila l'ultima release annuale di JavaScript (ciò che raggiunge lo Stage 4), sostituendo tutti i vecchi preset. Inoltre, può compilare in base agli ambienti target specificati: sia per la modalità sviluppo (come l'ultima versione di un browser) che per build multiple (come una versione per IE e un'altra per browser evergreen).

Non rimuoviamo i preset Stage (babel-preset-stage-x)

MODIFICA: Li abbiamo rimossi, spiegazione qui

Possiamo sempre mantenerli aggiornati, ma probabilmente dobbiamo definire un sistema migliore di quello attuale per questi preset.

Attualmente, i preset di stage sono letteralmente solo un elenco di plugin che aggiorniamo manualmente dopo gli incontri TC39. Per renderli gestibili, dobbiamo consentire aggiornamenti di versione major per questi pacchetti "instabili". Parte del motivo è che la comunità ricreerebbe comunque questi pacchetti, quindi tanto vale farlo da un pacchetto ufficiale per poi poter fornire messaggi migliori, ecc.

Ridenominazioni: Pacchetti con Scope (@babel/x)

Ecco un sondaggio che ho fatto quasi un anno fa:

All'epoca, pochi progetti usavano pacchetti con scope, quindi molti non sapevano nemmeno che esistessero. Inoltre, bisognava pagare per un account npm org, mentre ora è gratuito (e supporta anche pacchetti non scoped). I problemi di ricerca dei pacchetti scoped sono risolti e i download count funzionano. L'unica cosa rimasta è che alcuni registri di terze parti non supportano ancora i pacchetti scoped, e penso che siamo a un punto in cui sarebbe irragionevole aspettare oltre.

Se volete sapere perché preferiamo i pacchetti scoped:

  • Assegnare nomi è difficile: non dovremo verificare se qualcuno ha usato la nostra convenzione di naming per i propri plugin

  • Similmente, il package squatting

    • A volte le persone creano babel-preset-20xx o altri pacchetti per scherzo, e dobbiamo aprire issue/email per riaverli.
    • Alcuni hanno pacchetti legittimi con lo stesso nome che volevamo usare.
    • Gli utenti vedono una nuova proposta in fase di merging (come optional chaining o pipeline operator) e decidono di forkarla e pubblicarla con lo stesso nome. Quando pubblichiamo, npm ci dice che il pacchetto esiste già 🤔. Poi devo contattarli e il supporto npm per riprendere il pacchetto e ripubblicare.
  • Come distinguere un pacchetto "ufficiale" da uno della comunità con lo stesso nome? Riceviamo segnalazioni di problemi da utenti che usano pacchetti non ufficiali scambiandoli per parte di Babel. Un esempio: un utente segnalava che babel-env riscriveva il suo file .babelrc, impiegando tempo a capire che non era babel-preset-env.

Quindi, è ovvio che dovremmo usare pacchetti scoped e, semmai, avremmo dovuto farlo prima 🙂!

Esempi del cambio di nome con scope:

  • babel-cli -> @babel/cli

  • babel-core -> @babel/core

  • babel-preset-env -> @babel/preset-env

Ridenominazioni: -proposal-

D'ora in poi, tutte le proposte includeranno -proposal- nel nome per segnalare che non sono ancora parte ufficiale di JavaScript.

Quindi @babel/plugin-transform-class-properties diventa @babel/plugin-proposal-class-properties, e lo rinomineremo quando raggiungerà lo Stage 4.

Ridenominazioni: Rimozione dell'anno dal nome del plugin

I vecchi plugin includevano l'anno nel nome, ma ora non è più necessario.

Quindi @babel/plugin-transform-es2015-classes diventa @babel/plugin-transform-classes.

Poiché gli anni riguardavano solo es3/es2015, non abbiamo modificato nulla per es2016 o es2017. Tuttavia, stiamo deprecando quei preset in favore di preset-env, mentre per la revisione dei template literal l'abbiamo semplicemente aggiunta alla trasformazione esistente per semplicità.

Dipendenze Peer + Integrazioni

Stiamo introducendo una dipendenza peer su @babel/core per tutti i plugin (@babel/plugin-class-properties), preset (@babel/preset-env) e pacchetti di primo livello (@babel/cli, babel-loader).

Le peerDependencies sono dipendenze che il tuo codice si aspetta di utilizzare, a differenza delle dipendenze usate solo come dettagli implementativi. — Stijn de Witt via StackOverflow.

babel-loader aveva già una peerDependency su babel-core, quindi questa modifica la cambia semplicemente in @babel/core. Questo serve per evitare che le persone installino questi pacchetti sulla versione sbagliata di Babel.

Per gli strumenti che hanno già una peerDependency su babel-core e non sono pronti per un aggiornamento maggiore (poiché modificare la peer dependency è un cambiamento breaking), abbiamo pubblicato una nuova versione di babel-core per gestire la transizione: babel-core@7.0.0-bridge.0. Per maggiori informazioni consulta questo issue.

Allo stesso modo, pacchetti come gulp-babel, rollup-plugin-babel, ecc., avevano babel-core come dipendenza. Ora avranno semplicemente una peerDependency su @babel/core. Ciò permette a questi pacchetti di non dover incrementare la versione major quando l'API di @babel/core non cambia.

#5224 Pubblicazione Indipendente dei Pacchetti Sperimentali

Ne parlo in The State of Babel nella sezione Versioning. Github Issue

Ricorderete che dopo Babel 6, Babel è diventato un insieme di pacchetti npm con un proprio ecosistema di preset e plugin personalizzati.

Tuttavia da allora abbiamo sempre usato un sistema di versionamento "fissato/sincronizzato" (nessun pacchetto era alla versione v7.0 o superiore). Quando rilasciamo una nuova versione come v6.23.0, solo i pacchetti con codice sorgente aggiornato vengono pubblicati con la nuova versione, mentre gli altri rimangono invariati. Questo sistema funziona perché usiamo ^ nelle nostre dipendenze.

Purtroppo questo sistema richiede che una versione major venga rilasciata per tutti i pacchetti quando anche un solo pacchetto ne ha bisogno. Ciò significa fare tanti piccoli breaking change (non necessari) oppure raggruppare molti cambiamenti breaking in un unico rilascio. Invece, vogliamo differenziare i pacchetti sperimentali (Stage 0, ecc.) dal resto (es2015).

Questo significa che intendiamo effettuare aggiornamenti major per i plugin delle proposte sperimentali quando cambia la specifica, invece di aspettare di aggiornare tutto Babel. Quindi qualsiasi cosa allo Stage < 4 sarà soggetta a breaking change sotto forma di aggiornamenti major, lo stesso vale per gli stessi preset Stage (se non li abbandoneremo del tutto).

Questo va di pari passo con la nostra decisione di rinominare i plugin per le proposte TC39 usando il nome -proposal-. Se la specifica cambia, faremo un aggiornamento major al plugin e al preset a cui appartiene (invece di rilasciare una patch che potrebbe rompere il codice). Dovremo poi deprecare le vecchie versioni e creare un'infrastruttura per aggiornare automaticamente gli utenti, così che tutti siano allineati con l'evoluzione della specifica (ed evitare situazioni di stallo come successo con i decoratori).

L'opzione env in .babelrc non è deprecata!

A differenza di quanto detto nel post precedente, abbiamo corretto il comportamento di merge rendendolo più coerente.

La configurazione in env ha priorità superiore rispetto agli elementi root della configurazione, e invece di usare un approccio ibrido, plugin e preset ora vengono uniti in base alla loro identità. Quindi puoi fare:

JavaScript
{
presets: [
['env', { modules: false}],
],
env: {
test: {
presets: [
'env'
],
}
},
}

con BABEL_ENV=test, che sostituirà la configurazione env root con quella di test, che non ha opzioni.

Supporto per class A extends Array (caveat più datato)

Babel avvolgerà automaticamente qualsiasi built-in nativo come Array, Error, HTMLElement ecc. in modo che questa funzionalità funzioni senza problemi durante la compilazione delle classi.

Velocità

preset-env: "useBuiltins": "usage"

babel-preset-env ha introdotto la possibilità di compilare la sintassi per diversi target e, tramite l'opzione useBuiltIns, di aggiungere solo i polyfill non supportati dagli ambienti target.

Con questa opzione, un codice come:

JavaScript
import "babel-polyfill";

Può trasformare in

JavaScript
import "core-js/modules/es7.string.pad-start";
import "core-js/modules/es7.string.pad-end";
// ...

se l'ambiente di destinazione dovesse supportare polyfill diversi da padStart o padEnd.

Per ottimizzare ulteriormente, dovremmo importare solo i polyfill effettivamente "utilizzati" nel codice. Perché importare padStart se non viene nemmeno usato?

"useBuiltins": "usage" rappresenta il nostro primo tentativo in questa direzione. Aggiunge un'importazione all'inizio di ogni file solo se rileva l'utilizzo nel codice. Questo approccio consente di importare la quantità minima necessaria di polyfill (solo se l'ambiente target non li supporta).

Se usi Promise nel tuo codice, verrà importato all'inizio del file (se il target non lo supporta). I bundler deduplicheranno il file se identico, evitando così importazioni multiple.

JavaScript
import "core-js/modules/es6.promise";
var a = new Promise();
JavaScript
import "core-js/modules/es7.array.includes";
[].includes
a.includes

Con l'inferenza dei tipi possiamo determinare se un metodo come .includes si riferisce a un array. I falsi positivi sono accettabili provvisoriamente poiché comunque preferibili all'importazione completa del polyfill.

Aggiornamenti Vari

  • babel-template è più veloce/facile da usare

  • regenerator rilasciato sotto licenza MIT - dipendenza per compilare generatori/async

  • Opzione "lazy" per il plugin modules-commonjs tramite #6952

  • Possibilità di usare envName: "something" in .babelrc o via CLI babel --envName=something senza ricorrere a process.env.BABEL_ENV o process.env.NODE_ENV

  • ["transform-for-of", { "assumeArray": true }] per convertire tutti i loop for-of in array standard

  • Esclusione di transform-typeof-symbol in modalità loose per preset-env #6831

  • Merge di PR per messaggi d'errore migliori con errori sintattici

Cose da Fare Prima del Rilascio

  • Gestione lookup .babelrc (da completare prima del primo rilascio RC)

  • Supporto "overrides": configurazioni diverse basate su pattern glob

  • Logica di caching e invalidazione in babel-core.

  • Implementare o avere un piano per la gestione indipendente del versioning e dei polyfill rispetto agli helper, così da non essere vincolati esplicitamente a core-js 2 o 3. Gli utenti potrebbero avere dipendenze su una versione specifica e spesso non vorranno caricare entrambe.

  • Implementazione funzionante dei decoratori o implementazione legacy funzionale, con un percorso chiaro per adottare il comportamento dello standard corrente durante il ciclo di vita della versione 7.x.

Ringraziamenti

Un grande ringraziamento al nostro team di volontari: Logan che ha lavorato intensamente per risolvere problemi fondamentali di configurazione e non solo, Brian che ha preso in carico la manutenzione di preset-env e molto altro 😛, e Daniel sempre presente quando serve aiuto, sia per babel-loader che per il trasferimento dei repository babylon/babel-preset-env. Stesso riconoscimento a Nicolo, Sven, Artem e Jessica per il loro contributo nell'ultimo anno.

Attendo con impazienza il rilascio (sono stanco anch'io; è passato quasi un anno 😝), ma senza fretta inutile. Questo ciclo di release ha avuto alti e bassi, ma ho imparato molto e credo sia così anche per il resto del team.

E se quest'anno ho imparato qualcosa, è che dovrei seguire questo consiglio piuttosto che limitarmi a scriverlo.

Un grazie anche a Mariko per la spintarella gentile a completare questo post (in lavorazione da 2 mesi)