Vai al contenuto principale

File di Configurazione

Traduzione Beta Non Ufficiale

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

Tipologie di File di Configurazione

Babel supporta due formati di file di configurazione paralleli, utilizzabili insieme o separatamente.

History
VersionChanges
v7.21.0Support .babelrc.cts and babel.config.cts (Experimental)
v7.8.0Support .babelrc.mjs and babel.config.mjs
v7.7.0Support .babelrc.json, .babelrc.cjs, babel.config.json, babel.config.cjs
  • Configurazione globale del progetto

    • File babel.config.* con estensioni: .json, .js, .cjs, .mjs, .cts.
  • Configurazione relativa al file

    • File .babelrc.* con estensioni: .json, .js, .cjs, .mjs, .cts.
    • File .babelrc senza estensione.
    • File package.json con chiave "babel".

Configurazione Globale del Progetto

Novità in Babel 7.x: introduce il concetto di directory "root" che per default corrisponde alla directory di lavoro corrente. Per la configurazione globale, Babel cerca automaticamente un file babel.config.json (o equivalente con estensioni supportate) in questa directory root. In alternativa, è possibile specificare esplicitamente "configFile" per sovrascrivere questo comportamento.

Poiché i file di configurazione globali sono slegati dalla posizione fisica del file, sono ideali per impostazioni ad ampio raggio. Consentono a plugin e preset di applicarsi facilmente anche a file in node_modules o pacchetti symlinkati, configurazioni complesse in Babel 6.x.

Lo svantaggio principale è la dipendenza dalla directory di lavoro, che può creare difficoltà in monorepo se non corrisponde alla root. Vedere la documentazione monorepo per esempi pratici.

Disattivabile impostando "configFile" a false.

Configurazione Relativa al File

Babel carica file .babelrc.json, o equivalenti usando le estensioni supportate, risalendo la struttura delle directory partendo dal "filename" in compilazione (con limitazioni sotto indicate). Questo approccio è potente perché permette configurazioni indipendenti per sottosezioni di un pacchetto. Le configurazioni relative ai file vengono mergeate con quelle globali, risultando utili per override specifici (alternativa a "overrides").

Considerazioni importanti per le configurazioni relative:

  • La ricerca si interrompe al primo package.json trovato: una configurazione relativa si applica solo al pacchetto corrente.

  • Il "filename" in compilazione deve trovarsi in pacchetti "babelrcRoots", altrimenti la ricerca salta.

Questo implica che:

  • I file .babelrc.json si applicano solo ai file del proprio pacchetto

  • I file .babelrc.json in pacchetti non root di Babel vengono ignorati a meno di abilitarli con "babelrcRoots".

Vedere la documentazione monorepo per configurazioni avanzate. Disattivabile impostando "babelrc" a false.

Differenze nel caricamento .babelrc tra 6.x e 7.x

Utenti di Babel 6.x dovrebbero notare due nuove restrizioni introdotte nella 7.x per risolvere problematiche comuni:

  • I file .babelrc venivano applicati alle dipendenze in node_modules, spesso in modo imprevisto.

  • I file .babelrc non venivano applicati alle dipendenze collegate simbolicamente in node_modules quando ci si aspettava che si comportassero come dipendenze normali.

  • I file .babelrc all'interno delle dipendenze node_modules venivano rilevati, anche se i plugin e i preset al loro interno generalmente non erano installati e potrebbero non essere validi nella versione di Babel che compila il file.

Questi casi causeranno principalmente problemi per gli utenti con una struttura monorepo, perché se si dispone di

.babelrc
packages/
mod1/
package.json
src/index.js
mod2/
package.json
src/index.js

la configurazione verrà ora completamente ignorata, poiché attraversa un confine di package.

Un'alternativa sarebbe creare un file .babelrc in ogni sotto-package che utilizzi "extends" come

.babelrc.json
{ "extends": "../../.babelrc" }

Purtroppo, questo approccio può risultare un po' ripetitivo e, a seconda di come viene utilizzato Babel, potrebbe richiedere l'impostazione di "babelrcRoots".

Considerando ciò, potrebbe essere più desiderabile rinominare il file .babelrc in un file a livello di progetto "babel.config.json". Come menzionato nella sezione a livello di progetto sopra, ciò potrebbe quindi richiedere l'impostazione esplicita di "configFile" poiché Babel non troverà il file di configurazione se la directory di lavoro non è corretta.

Estensioni di file supportate

Babel può essere configurato utilizzando qualsiasi estensione di file supportata nativamente da Node.js, come menzionato nella sezione Tipi di file di configurazione:

  • babel.config.json e .babelrc.json vengono analizzati come JSON5 e devono contenere un oggetto corrispondente al formato delle opzioni accettate da Babel. Sono supportati a partire dalla versione v7.7.0.

    Consigliamo di utilizzare questo tipo di file ovunque sia possibile: i file di configurazione JS sono utili se si dispone di configurazioni complesse condizionali o calcolate al momento della build. Tuttavia, lo svantaggio è che le configurazioni JS sono meno analizzabili staticamente e quindi hanno effetti negativi sulla cache, linting, autocompletamento dell'IDE, ecc. Dato che babel.config.json e .babelrc.json sono file JSON statici, consentono ad altri strumenti che utilizzano Babel, come i bundler, di memorizzare nella cache i risultati di Babel in modo sicuro, il che può rappresentare un enorme vantaggio in termini di prestazioni della build.

  • babel.config.cjs e .babelrc.cjs consentono di definire la configurazione come CommonJS, utilizzando module.exports. Sono supportati a partire dalla versione v7.7.0.

  • babel.config.mjs e .babelrc.mjs utilizzano i moduli ECMAScript nativi. Sono supportati da Node.js 13.2+ (o versioni precedenti tramite il flag --experimental-modules). Si prega di ricordare che i moduli ECMAScript nativi sono asincroni (ecco perché import() restituisce sempre una promise!): per questo motivo, i file di configurazione .mjs genereranno un errore quando Babel viene chiamato in modo sincrono. Sono supportati a partire dalla versione v7.8.0.

  • babel.config.js e .babelrc.js si comportano come gli equivalenti .mjs quando il file package.json contiene l'opzione "type": "module", altrimenti sono esattamente uguali ai file .cjs.

  • babel.config.cts e .babelrc.cts consentono di definire la configurazione come Typescript + CommonJS. È necessario installare @babel/preset-typescript oppure eseguire Babel utilizzando ts-node.

    nota

    🚧 Questa funzionalità è sperimentale. Non è ancora possibile utilizzare i file babel.config.ts e babel.config.mts, in attesa della stabilizzazione dell'API di caricamento ESM di Node.js.

I file di configurazione JavaScript possono esportare un oggetto oppure una funzione che, quando chiamata, restituirà la configurazione generata. Le configurazioni che restituiscono una funzione hanno alcuni poteri speciali perché possono accedere a un'API esposta da Babel stesso. Per maggiori informazioni, consultare API della funzione di configurazione.

nota

Per motivi di compatibilità, .babelrc è un alias di .babelrc.json.

Repository Monorepo

I repository strutturati come monorepo contengono solitamente molti pacchetti, il che significa che spesso incontrano le limitazioni menzionate nella configurazione relativa ai file e nel caricamento dei file di configurazione in generale. Questa sezione mira ad aiutare gli utenti a comprendere come gestire la configurazione nei monorepo.

Nelle configurazioni monorepo, l'aspetto fondamentale da comprendere è che Babel considera la directory di lavoro corrente come "root" logica, causando problemi se si desidera eseguire strumenti Babel all'interno di un sotto-pacchetto specifico senza applicare Babel all'intero repository.

Separatamente, è importante decidere se utilizzare file .babelrc.json o un unico file centrale babel.config.json. I file .babelrc.json non sono più indispensabili per configurazioni specifiche delle sottocartelle come in Babel 6, pertanto spesso in Babel 7 sono superflui a favore di babel.config.json.

File babel.config.json principale

Il primo passo in qualsiasi struttura monorepo dovrebbe essere la creazione di un file babel.config.json nella root del repository. Questo definisce il concetto fondamentale di directory base per Babel. Anche se si desidera utilizzare file .babelrc.json per configurare singoli pacchetti, è importante avere questo file per opzioni a livello repository.

Spesso è possibile inserire l'intera configurazione del repository nel file babel.config.json principale. Utilizzando "overrides", è possibile specificare facilmente configurazioni applicabili solo a determinate sottocartelle, approccio spesso più chiaro rispetto alla creazione di molti file .babelrc.json.

Il primo problema che incontrerete è che Babel, per impostazione predefinita, si aspetta di trovare file babel.config.json nella directory impostata come "root". Ciò significa che se create un babel.config.json ma eseguite Babel all'interno di un singolo pacchetto, ad esempio:

Shell
cd packages/some-package;
babel src -d dist

la "root" utilizzata da Babel in quel contesto non sarà la root del monorepo, impedendo il corretto rilevamento del file babel.config.json.

Se tutti gli script di build vengono eseguiti relativamente alla root del repository, il funzionamento dovrebbe essere corretto. Tuttavia, se il processo di compilazione Babel viene avviato da un sottopacchetto, è necessario indicare a Babel dove cercare la configurazione. Il metodo consigliato è l'opzione "rootMode" con valore "upward", che fa risalire Babel dalla directory di lavoro corrente alla ricerca del file babel.config.json, utilizzandone la posizione come valore "root".

Un metodo efficace per verificare il rilevamento della configurazione è inserire una chiamata console.log() nel file (se si tratta di un JavaScript babel.config.json): il log verrà eseguito al primo caricamento da parte di Babel.

L'impostazione di questo valore varia a seconda del progetto, ma ecco alcuni esempi:

CLI

Shell
babel --root-mode upward src -d lib

@babel/register

JavaScript
require("@babel/register")({
rootMode: "upward",
});

Webpack

webpack.config.js
module: {
rules: [
{
loader: "babel-loader",
options: {
rootMode: "upward",
},
},
];
}

Jest

Jest è spesso installato nella root del monorepo e potrebbe non richiedere configurazioni aggiuntive, ma se installato per singolo pacchetto la configurazione può diventare più complessa.

L'elemento principale consiste nel creare un file transformer personalizzato per Jest che inglobi il comportamento predefinito di babel-jest per impostare l'opzione, ad esempio:

wrapper.js
module.exports = require("babel-jest").default.createTransformer({
rootMode: "upward",
});

Dopo aver salvato questo file, lo si utilizzerà al posto di babel-jest nelle opzioni Jest tramite l'opzione transform:

jest.config.js
"transform": {
"^.+\\.jsx?$": "./path/to/wrapper.js"
},

quindi tutti i file JS verranno elaborati dalla tua versione di babel-jest con l'opzione abilitata.

nota

Quando si utilizza babel-jest < 27, devi omettere la parte .default: require("babel-jest").createTransformer({ ....

Altri

Esistono tantissimi strumenti, ma il punto fondamentale è che richiedono l'opzione rootMode abilitata se la directory di lavoro non corrisponde già alla root del monorepo.

File .babelrc.json nei sottopacchetti

Analogamente a come i file babel.config.json devono trovarsi nella "root", i file .babelrc.json devono essere nel pacchetto principale per impostazione predefinita. Ciò significa che, allo stesso modo in cui la directory di lavoro influisce sul caricamento di babel.config.json, influisce anche sul caricamento di .babelrc.json.

Supponendo che tu abbia già caricato correttamente il file babel.config.json come discusso sopra, Babel elaborerà solo i file .babelrc.json all'interno di quel pacchetto principale (e non nei sottopacchetti), quindi ad esempio

package.json
babel.config.js
packages/
mod/
package.json
.babelrc.json
index.js

compilare il file packages/mod/index.js non caricherà packages/mod/.babelrc.json perché questo .babelrc.json si trova in un sottopacchetto, non nel pacchetto principale.

Per abilitare l'elaborazione di quel .babelrc.json, dovrai utilizzare l'opzione "babelrcRoots" all'interno del tuo file babel.config.json per fare in modo

JavaScript
babelrcRoots: [
".",
"packages/*",
],

che Babel consideri tutti i pacchetti packages/* abilitati a caricare file .babelrc.json, insieme alla root originale del repository.

API della Funzione di Configurazione

I file di configurazione JS possono esportare una funzione che riceve l'API di configurazione come parametro:

babel.config.js
module.exports = function(api) {
return {};
};

L'oggetto ConfigAPI api fornisce le seguenti proprietà o metodi:

api.version

Tipo: string

La stringa della versione di Babel che sta caricando il file di configurazione.

api.cache

Le configurazioni JS sono ottime perché possono calcolare una configurazione al volo, ma lo svantaggio è che rendono più complessa la gestione della cache. Babel vuole evitare di rieseguire la funzione di configurazione ogni volta che un file viene compilato, perché ciò comporterebbe la riesecuzione di tutte le funzioni di plugin e preset referenziati in quella configurazione.

Per evitare ciò, Babel si aspetta che gli utenti delle funzioni di configurazione specifichino come gestire la cache all'interno di un file di configurazione.

  • api.cache.forever() - Memorizza permanentemente la configurazione calcolata senza richiamare più la funzione.

  • api.cache.never() - Non memorizza in cache questa configurazione e riesegue la funzione ogni volta.

  • api.cache.using(() => process.env.NODE_ENV) - Memorizza in cache in base al valore di NODE_ENV. Ogni volta che la callback using restituisce un valore diverso da quello atteso, l'intera funzione di configurazione verrà richiamata e una nuova voce verrà aggiunta alla cache.

  • api.cache.invalidate(() => process.env.NODE_ENV) - Cache basata sul valore di NODE_ENV. Ogni volta che la callback using restituisce un valore diverso da quello atteso, l'intera funzione di configurazione verrà richiamata e tutte le voci nella cache saranno sostituite con il nuovo risultato.

  • api.cache(true) - Equivalente a api.cache.forever()

  • api.cache(false) - Equivalente a api.cache.never()

Poiché il risultato effettivo della callback viene utilizzato per verificare la validità della voce di cache, si raccomanda di:

  • Mantenere le callback piccole e prive di effetti collaterali.

  • Far restituire alle callback valori con il minor range possibile. Ad esempio, l'utilizzo .using(() => process.env.NODE_ENV) menzionato sopra non è ideale perché creerebbe un numero imprevedibile di voci di cache in base ai valori rilevati di NODE_ENV. Sarebbe più sicuro usare .using(() => process.env.NODE_ENV === "development") poiché la voce di cache potrebbe essere solo true o false.

api.env(...)

Dato che NODE_ENV è un metodo comune per modificare comportamenti, Babel include un'API specifica per questo scopo. Questa funzione permette di verificare rapidamente "envName" con cui Babel è stato caricato, che tiene conto di NODE_ENV se non è impostato alcun ambiente sovrascritto.

Disponibile in diverse forme:

  • api.env("production") restituisce true se envName === "production".

  • api.env(["development", "test"]) restituisce true se ["development", "test"].includes(envName).

  • api.env() restituisce la stringa corrente di envName.

  • api.env(envName => envName.startsWith("test-")) restituisce true se l'ambiente inizia con "test-".

Questa funzione utilizza internamente api.cache per garantire che Babel sia consapevole della dipendenza da un envName specifico. Non dovrebbe essere usata insieme a api.cache.forever() o api.cache.never().

api.caller(cb)

Questa API permette di accedere ai dati caller passati a Babel. Poiché più istanze di Babel possono essere eseguite nello stesso processo con valori caller diversi, questa funzione configura automaticamente api.cache nello stesso modo di api.env().

Il valore caller è disponibile come primo parametro della funzione di callback. È particolarmente utile con espressioni come:

JavaScript
function isBabelRegister(caller) {
return !!(caller && caller.name === "@babel/register");
}

module.exports = function(api) {
const isRegister = api.caller(isBabelRegister);

return {
// ...
};
};

per modificare il comportamento della configurazione in base a un ambiente specifico.

api.assertVersion(range)

Sebbene api.version sia generalmente utile, a volte è preferibile dichiarare semplicemente la propria versione. Questa API offre un modo semplice per farlo con:

JavaScript
module.exports = function(api) {
api.assertVersion("^7.2");

return {
// ...
};
};