Roadmap di Babel
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: trueinbabel.config.json(o potrebbe persino diventare l'impostazione predefinita in futuro — non può esserlo di default perché@babel/eslint-parsernon 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@3da@babel/preset-envin Babel 8, incoraggiando gli utenti a migrare ababel-plugin-polyfill-corejs3(che è ciò che@babel/preset-envutilizza internamente a partire dalla versione 7.10.0) -
Possiamo mantenere il supporto per
core-js@3in@babel/preset-env, ma non migrarlo a@babel/corequando 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,
defaultso>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:
-
Il REPL non supporta la configurazione
assumptions. Nonostante disponiamo di un mini-REPL dedicato per singola assunzione su https://babel.dev/assumptions, attualmente non possiamo mostrare come questeassumptionspossano funzionare insieme. -
Il REPL non supporta le opzioni dei plugin. Alcuni plugin richiedono opzioni obbligatorie, come
@babel/plugin-proposal-record-and-tuplee@babel/plugin-proposal-decoratorshttps://github.com/babel/website/issues/1292, https://github.com/babel/website/issues/2224, https://github.com/babel/website/pull/1970
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!)