7.8.0 rilasciato: ECMAScript 2020, file di configurazione .mjs e miglioramenti a @babel/cli
Questa pagina è stata tradotta da PageTurner AI (beta). Non ufficialmente approvata dal progetto. Hai trovato un errore? Segnala problema →
Questa è la prima release dell'anno! 🎉
Babel 7.8.0 supporta per impostazione predefinita le nuove funzionalità di ECMAScript 2020: non è più necessario abilitare singoli plugin per il nullish coalescing (??), l'optional chaining (?.) e l'import() dinamico con preset-env.
Abbiamo inoltre completato l'allineamento dei nostri diversi file di configurazione con i formati supportati nativamente da Node.js, un processo iniziato con la release 7.7.0.
Infine, la CLI di Babel ora supporta due nuove opzioni: --out-file-extension e --copy-ignored.
Potete leggere l'intero changelog su GitHub.
Un ringraziamento speciale ad Abdul Ali, Jack Isherwood, Jayen Ashar, James Beavers, Klaus Meinhardt, Oleksandr Fediashov, Siddhant N Trivedi, Tsubasa Nakayama, Yordis Prieto e ZYSzys per le loro prime PR!
Ringraziamo inoltre Thomas Smith per aver offerto volontariamente il suo aiuto nella manutenzione del fondamentale plugin di syntax highlighting babel-sublime, e diamo il benvenuto a Raja Sekar, il nostro nuovo membro dell'organizzazione Babel!
Se tu o la tua azienda desiderate supportare Babel e l'evoluzione di JavaScript ma non sapete come, potete donare sul nostro Open Collective e, ancora meglio, collaborare direttamente con noi all'implementazione di nuove proposte ECMAScript! Essendo un progetto guidato da volontari, dipendiamo dal supporto della comunità per finanziare i nostri sforzi nel supportare la vasta gamma di utenti JavaScript. Scriveteci a team@babeljs.io per discutere ulteriormente!
Abbiamo recentemente pubblicato un post sul finanziamento che dettaglia i nostri piani e obiettivi. Dateci un'occhiata!
Supporto predefinito per ECMAScript 2020 (#10811, #10817, #10819, #10843)
Durante l'ultimo incontro, TC39 ha spostato allo Stage 4 sia la proposta del nullish coalescing che quella dell'optional chaining!
L'operatore di nullish coalescing consente di fornire un valore di fallback quando un'espressione restituisce null o undefined:
const name = person.fullName ?? "Anonymous";
console.log(`Hello, ${name}!`);
Questo comportamento è simile a quello dell'operatore OR logico (||). La differenza è che mentre || verifica i valori "falsy" (come undefined, null, false, 0, 0n e ""), ?? controlla solo i valori "nullish". Questo approccio si allinea meglio al modello mentale di "valore non fornito" e funziona più efficacemente con valori potenzialmente falsy ma validi:
const element = { index: 0, value: "foo" };
const index = element.index ?? -1; // 0 :D
const index = element.index || -1; // -1 :(
La proposta dell'optional chaining utilizza lo stesso concetto di "valori nullish", consentendo accessi opzionali alle proprietà su valori che potrebbero essere nullish. Supporta inoltre chiamate di funzioni opzionali e proprietà calcolate.
const city = person.address?.city; // person.address could be not defined
const isNeighbor = person.address?.isCloseTo(me);
person.sayHayUsing?.("Twitter"); // The person.sayHayUsing method could be not defined
Ora puoi utilizzare queste nuove funzionalità nel tuo codice in tutta sicurezza! Se stai già usando @babel/preset-env, puoi usare questi due operatori e verranno compilati in base ai tuoi target, proprio come qualsiasi altra funzionalità ECMAScript. Se utilizzavi direttamente @babel/plugin-proposal-nullish-coalescing-operator o @babel/plugin-proposal-optional-chaining, puoi rimuoverli dalla tua configurazione:
{
"presets": [
["@babel/env", { "targets": ["last 2 versions"] }]
],
"plugins": [
- "@babel/proposal-optional-chaining",
- "@babel/proposal-nullish-coalescing-operator"
]
}
Queste funzionalità sono ora abilitate di default anche in @babel/parser: se lo usavi direttamente, puoi rimuovere i plugin parser nullishCoalescingOperator e optionalChaining. Abbiamo anche abilitato il parsing per import() dinamico (già incluso in @babel/preset-env dalla v7.5.0), quindi puoi tranquillamente rimuovere il plugin dynamicImport.
Supporto per tutte le estensioni dei file di configurazione (#10783 e #10903)
Babel 6 supportava un unico file di configurazione basato su JSON: .babelrc.
In Babel 7.0.0 abbiamo introdotto babel.config.js (che ha una logica di risoluzione diversa) e .babelrc.js. I file di configurazione JavaScript possono essere utili per scenari che richiedono maggiore flessibilità. Questa era la situazione:
| Node.js file type | babel.config.__ | .babelrc.__ |
|---|---|---|
.js | ✔️ Supported | ✔️ Supported |
.json | ❌ Not supported | ❔ Supported, with implicit extension |
Consigliamo vivamente di leggere le differenze tra babel.config.js e .babelrc.js!
Più recentemente, Node.js 13.2.0 è stato rilasciato, aggiungendo il supporto per i moduli ECMAScript nativi e le estensioni di file .cjs e .mjs. In Babel 7.7.0 abbiamo aggiunto il supporto per i file di configurazione .cjs per consentire agli utenti di abilitare "type": "module" nel loro package.json senza interrompere Babel, oltre al supporto per babel.config.json, che consente una configurazione statica a livello di progetto.
| Node.js file type | babel.config.__ | .babelrc.__ |
|---|---|---|
.js | ✔️ Supported when "type": "module" is not enabled | ✔️ Supported when "type": "module" is not enabled |
.json | ✔️ Supported | ❔ Supported, with implicit extension |
.cjs | ✔️ Supported | ✔️ Supported |
.mjs | ❌ Not supported | ❌ Not supported |
Questa release allinea Babel ai tipi di file supportati nativamente da Node.js, consentendo .babelrc.json, babel.config.mjs e .babelrc.mjs.
| Node.js file type | babel.config.__ | .babelrc.__ |
|---|---|---|
.js | ✔️ Supported | ✔️ Supported |
.json | ✔️ Supported | ✔️ Supported |
.cjs | ✔️ Supported | ✔️ Supported |
.mjs | ✔️ Supported | ✔️ Supported |
Ricorda che i moduli ECMAScript sono asincroni: per questo motivo, ad esempio, non puoi require() e devi invece usare import(), che restituisce una promise.
Per questi motivi, possono essere utilizzati solo quando si chiama Babel tramite i punti di ingresso basati su promise o callback. Funzionano già con @babel/cli, babel-loader e gulp-babel, e funzioneranno con la prossima release di rollup-plugin-babel. Nota che non sono ancora supportati da babel-eslint.
Nuove opzioni CLI (#9144 e #10887)
Abbiamo aggiunto due nuovi flag a @babel/cli: --copy-ignored e --out-file-extension.
--copy-ignored può essere utilizzato per copiare i file che non vengono transpilati da Babel, sia perché sono ignorati tramite l'opzione CLI --ignore, sia perché "ignore" è impostato in un file di configurazione.
Per mantenere la compatibilità con le versioni precedenti, in Babel 7.8.4 il valore predefinito dell'opzione --copy-ignored è stato modificato in true. Per disabilitarla, puoi usare --no-copy-ignored.
Questo funziona in modo simile all'opzione --copy-files, ma --copy-files è pensata per copiare qualsiasi file che non viene transpilato perché non è JavaScript (ad esempio .css o .json), anziché file esplicitamente ignorati.
--out-file-extension permette di configurare l'estensione dei file generati da Babel. Ad esempio, se stai transpilando file .js contenenti moduli ECMAScript nativi in Node.js e vuoi generare file CommonJS, potresti aver bisogno di usare l'estensione .cjs:
$ babel src --out-dir lib-cjs --out-file-extension cjs
Preparativi per Babel 8
Abbiamo iniziato a lavorare alla release di Babel 8.0.0 nella nostra issue ombrello: #10746.
Babel 8 conterrà solo cambiamenti breaking: rilasceremo una versione minore lo stesso giorno, contenente tutte le correzioni di bug e le nuove funzionalità che altrimenti sarebbero state incluse in 8.0.0.
Sebbene non prevediamo un percorso di migrazione complesso, ci sono due aspetti che vogliamo portare alla vostra attenzione:
Estrazione del parser dei target e dei dati di compatibilità da preset-env (#10899)
Attualmente vari preset di terze parti utilizzano la logica interna di @babel/preset-env per interpretare i target di compilazione o recuperare informazioni sui plugin e polyfill necessari.
Abbiamo deciso di supportare ufficialmente questi due casi d'uso fornendo due nuovi pacchetti pubblici:
-
@babel/helper-compilation-targets, che esporta una funzione per normalizzare i target specificati e altre utility correlate:JavaScriptimport getTargets from "@babel/helper-compilation-targets";
getTargets({
browsers: ["last 2 chrome versions"],
node: 10,
}) ==
{
chrome: "77.0.0",
node: "10.0.0",
}; -
@babel/compat-data, che contiene una raccolta di file JSON dove memorizziamo tutte le versioni dei browser per cui è richiesto ogni plugin o polyfill dicore-js@2. È generato principalmente dacompat-table, ma potremmo aggiungere altre fonti in futuro. Se ti servono dati per i polyfill dicore-js@3, puoi usarecore-js-compat.
Pianifichiamo di vietare l'uso di file interni a partire da Babel 8. Se fai affidamento su altre API interne, faccelo sapere!
Introduzione di una validazione AST più rigorosa (opt-in) (#10917)
@babel/types esegue già molti controlli per garantire che l'AST che stai costruendo sia valido. Ad esempio, questo codice genererà un errore perché non puoi usare uno statement al posto di un'espressione:
// foo = if (true) {}
t.assignmentExpression(
"=",
t.identifier("foo"),
t.ifStatement(t.booleanLiteral(true), t.blockStatement([]))
);
Stiamo introducendo una validazione più rigorosa per prevenire AST ancora più invalid: non solo dal punto di vista della struttura ad albero, ma anche assicurando che i nodi nella posizione corretta contengano informazioni valide. Ad esempio, a partire da Babel 8 t.identifier("123") non sarà permesso perché 123 non è un identificatore valido.
Non possiamo abilitare questi controlli in Babel 7.8.0 perché il rischio di rompere plugin esistenti è troppo alto, ma ti incoraggiamo vivamente ad abilitarli usando la variabile d'ambiente BABEL_TYPES_8_BREAKING=true e ad aprire issue (o meglio, PR!) per correggere i plugin che utilizzi e che non funzioneranno con Babel 8.