Vai al contenuto principale

Roadmap di Babel

Traduzione Beta Non Ufficiale

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

Questo documento delinea alcuni dei miglioramenti che i membri del nostro team intendono sviluppare quest'anno.

Non si tratta di un elenco completo di tutte le nuove funzionalità o modifiche importanti che introdurremo in Babel, ma offre una buona panoramica della direzione generale del progetto. Potremmo non completare tutti i punti elencati o posticiparne alcuni all'anno prossimo. Alcuni hanno punti di inizio e fine ben definiti, mentre altri richiedono ulteriori ricerche o RFC.

Se la tua azienda è interessata a sponsorizzare direttamente uno specifico punto, contattaci!

Roadmap 2021 di Babel

Babel 8

Parliamo del rilascio di Babel 8 da oltre un anno (inizialmente programmato circa un anno fa)! Tuttavia, siamo ora più vicini che mai alla sua pubblicazione!

La maggior parte delle attività rimanenti è nell'issue di tracciamento, ma permangono alcuni blocchi:

  • Intendiamo rimuovere il supporto per Node.js 10, la cui manutenzione cesserà il 2021-04-30.

  • Vorremmo rilasciare Babel come pacchetto ESM puro. Stiamo convertendo i sorgenti per la compatibilità con l'implementazione ESM di Node.js, studiando come semplificare la compilazione da ESM a CJS per gli utenti attuali.

  • Stiamo allineando il nostro AST TypeScript con il progetto typescript-eslint. Gli AST sono quasi identici, ma servono piccole modifiche breaking per l'allineamento completo.

  • La nostra infrastruttura di release non supporta ancora pre-release o branch "main" multipli (uno per Babel 8 e uno per Babel 7).

  • Non abbiamo ancora definito una politica di manutenzione per Babel 7.

Implementare nuove proposte TC39

Babel attualmente analizza tutte le proposte di Stage 3 e le trasforma tranne top-level await, import assertions e moduli JSON (gestibili meglio dai bundler tramite dependency graph).

Supportiamo tutte le proposte di Stage 2 tranne:

  • La nuova iterazione dei decoratori (da implementare sia parsing che trasformazione);

  • La trasformazione per i Module Blocks (il parsing è stato implementato in Babel 7.13.0).

Implementeremo i decoratori e valuteremo se e come trasformare i module blocks.

Pur non supportando molte proposte di Stage 1, ci sono aggiornamenti recenti per l'operatore pipeline e le do expressions. Essendo già supportate e molto attese dalla community, aggiorneremo le implementazioni.

Altre proposte (come il pattern matching) non sono ancora implementate perché i loro champion prevedono modifiche significative a sintassi e semantica. Monitoriamo attivamente gli sviluppi e le implementeremo non appena si stabilizzeranno.

Integrare @babel/preset-env in @babel/core

Una configurazione minima di trasformazione Babel richiede almeno tre pacchetti:

  • @babel/core

  • @babel/preset-env

  • un "runner" di Babel (@babel/cli, babel-loader, @rollup/plugin-babel, ecc.)

L'integrazione diretta di @babel/preset-env in @babel/core offre due grandi vantaggi:

  • Renderà più semplice configurare Babel in progetti semplici: basterà abilitare un'opzione compileJS: true in babel.config.json (o potrebbe persino diventare l'impostazione predefinita in futuro — non può esserlo di default perché @babel/eslint-parser non compila il sorgente)

  • Garantirà che le versioni dei plugin siano sincronizzate con la versione di @babel/core, evitando la maggior parte dei bug causati da versioni di pacchetti non corrispondenti o incompatibili

  • Quando passeremo a ESM, sarà difficile risolvere e caricare i plugin in modo sincrono in transformSync. Questo evita che diventi un problema.

È già presente una RFC per spostare i plugin per le funzionalità stabili di ECMAScript in @babel/core, che è il primo passo in questa direzione.

Con l'attuale architettura di @babel/preset-env, dovremmo gestire in modo speciale i plugin ufficiali per abilitarli o disabilitarli automaticamente in base ai targets. Tuttavia, questo approccio presenta due inconvenienti:

  • I dati di compatibilità per un plugin specifico sono completamente separati dall'implementazione del plugin (non sono nemmeno una dipendenza, ma piuttosto una sorta di dipendenza peer implicita interna: plugin -> @babel/core -> @babel/compat-data);

  • I plugin ufficiali riceverebbero un trattamento speciale da @babel/core, ma vogliamo assicurarci che i plugin di terze parti abbiano le stesse capacità di quelli ufficiali.

Continuare lo sviluppo del progetto babel-polyfills

Abbiamo già deciso di rimuovere il supporto per core-js@2 da @babel/preset-env in Babel 8. Vogliamo anche smettere di promuovere uno specifico polyfill di terze parti, perché potrebbe dare agli utenti l'impressione che faccia parte di Babel stesso.

Questo potrebbe avvenire in due modi diversi:

  • Rimuoviamo semplicemente core-js@3 da @babel/preset-env in Babel 8, incoraggiando gli utenti a migrare a babel-plugin-polyfill-corejs3 (che è ciò che @babel/preset-env utilizza internamente a partire dalla versione 7.10.0)

  • Possiamo mantenere il supporto per core-js@3 in @babel/preset-env, ma non migrarlo a @babel/core quando sposteremo i plugin di trasformazione.

Qualunque strada prendiamo, vorremmo offrire almeno un'alternativa ai nostri utenti quando dovranno aggiornare l'integrazione di core-js nella loro configurazione. core-js è un ottimo polyfill che garantisce la massima conformità alle specifiche, ma gli utenti potrebbero preferire diversi compromessi.

(Nicolò) sta lavorando con @ljharb per assicurarsi che il progetto @es-shims supporti almeno tutte le funzionalità ES2015+ (in realtà miriamo a ES5+), in modo che gli utenti di Babel siano liberi di scegliere tra almeno due opzioni.

Questo deve avvenire prima di rimuovere il supporto integrato per core-js@3, in modo che le persone interessate a es-shims non debbano migrare due volte.

Estendere l'uso di targets per trasformazioni granulari

Fin dall'inizio, @babel/preset-env ha utilizzato l'opzione targets per abilitare o disabilitare automaticamente i plugin di trasformazione.

Tuttavia, non esiste una corrispondenza 1-a-1 tra i plugin di Babel e le funzionalità implementate nei browser.

Ad esempio, abbiamo un unico plugin per i diversi tipi di class field (pubbliche e private, statiche e di istanza), ma i browser presentano matrici di compatibilità variabili:

  • Firefox 73 e Safari 14 supportano solo i campi di istanza pubblici

  • Firefox 75+ supporta i campi di istanza e statici pubblici

  • Chrome 79+ supporta i campi pubblici e privati, ma non supporta i campi privati in alcune espressioni di optional chaining

  • Chrome 84+ supporta completamente i campi privati e anche i metodi privati

  • Safari TP 121 supporta completamente i campi privati (anche con ?.), ma non supporta i metodi privati

Creare un plugin per ogni funzionalità non è ottimale. Ad esempio, possiamo convertire i metodi privati in campi privati e poi, se necessario, convertirli in sintassi legacy. Tuttavia, possiamo generare output migliore/ottimizzato convertendo direttamente i metodi privati in sintassi legacy senza il passaggio intermedio, se sappiamo che devono essere transpilati.

Dalla versione Babel 7.13.0, possiamo leggere l'opzione targets direttamente all'interno di un plugin. Possiamo modificare i nostri plugin per eseguire automaticamente una compilazione parziale di determinate funzionalità ECMAScript, offrendo vantaggi nelle dimensioni dell'output e nelle prestazioni runtime.

Esempi Precedenti

Questo approccio non è del tutto nuovo. Grazie a una collaborazione con @_developit, in Babel 7.9.0 abbiamo introdotto una nuova opzione bugfixes: true per @babel/preset-env. Quando questa opzione è abilitata e si utilizza esmodules: true come target di compilazione, compiliamo solo parzialmente alcune funzionalità. Questo ci ha fatto inizialmente pensare a questa possibilità, ma le trasformazioni parziali attuali sono meno utili con target più moderni (ad esempio, defaults, not ie 11).

Utilizziamo già l'opzione targets per decidere se possiamo usare Object.assign durante la compilazione dello spread di oggetti o meno.

Azioni Prioritarie

Questo obiettivo può essere suddiviso in due macro-attività eseguibili in parallelo:

  • Dobbiamo identificare dove queste ottimizzazioni possono essere utili raccogliendo query browserslist reali e simulando l'evoluzione futura di query popolari (ad esempio, defaults o >2%, not dead).

  • Dobbiamo effettivamente implementare le ottimizzazioni necessarie, assicurandoci che funzionino correttamente con gli altri plugin (poiché aumenterebbero notevolmente il numero di possibili combinazioni di trasformazioni).

Studiare nuove assumptions del compilatore

In Babel 7.13.0 abbiamo introdotto una nuova opzione top-level assumptions, per formalizzare il comportamento della modalità loose e offrire un controllo più granulare agli utenti (che spesso possono abilitare solo alcune assunzioni).

Tuttavia, abbiamo incluso solo opzioni per assunzioni che già applicavamo in modalità loose. Possiamo ora studiare quali nuove assunzioni potrebbero servire ai nostri utenti.

Esistono già alcune proposte, come:

  • #8222 - assumere che tutte le importazioni ESM siano immutabili, evitando il codice necessario per i live bindings.

  • #11356 - assumere che le classi compilate non estendano classi native, evitando il costo prestazionale runtime per istanziare potenziali classi native.

Possiamo identificare nuove assunzioni da implementare tramite:

  • Verifica manuale delle funzionalità che compiliamo in output "non ovvi", solitamente causati da edge case irrilevanti per molti sviluppatori.

  • Richiesta di feedback alla community, poiché gli sviluppatori possono testare quali assunzioni funzionano sulle loro applicazioni.

Revisionare il Babel REPL

Il Babel REPL è un ambiente pratico per imparare come Babel trasforma il codice sorgente.

Limiti attuali:

Funzionalità desiderabili:

  • Integrazione con AST Explorer (utilizzando quello esistente)

  • Output su stderr con stack trace completo per i log degli errori

  • Output su stdout

  • Possibilità di cambiare versione di Babel dall'interfaccia utente

Almeno il 15% delle issue aperte su babel-website riguardano il REPL: https://github.com/babel/website/issues?q=is%3Aissue+is%3Aopen+label%3Arepl

Strumenti Didattici/Debugging

Relativamente al REPL/ASTExplorer, potremmo sviluppare più strumenti per supportare lo sviluppo di plugin, sia per noi che per sviluppatori terzi. Quest'area è piuttosto esplorativa: diverse visualizzazioni dell'AST, strumenti di debugging, ecc.

Alcuni progetti in corso su cui Henry ha lavorato saltuariamente:

  • Codesandbox per creare semplici plugin Babel, simile a https://astexplorer.net ma con configurazioni personalizzate.

  • Visualizzazione del mapping input-output per comprendere come Babel trasforma il codice. Utile anche per documentazione nell'introdurre nuovi sintassi agli utenti JavaScript.

  • Mapping input-output simile a una struttura di sourcemap. Permette di risalire al plugin che ha generato un output specifico, aiutando il debugging.

Per un esempio interattivo di ciò che abbiamo in mente: https://babel-explorer.netlify.app/ (cliccare e tenere premuto il mouse nel settore inferiore!)