Vai al contenuto principale

@babel/parser

Traduzione Beta Non Ufficiale

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

The Babel parser (previously Babylon) is a JavaScript parser used in Babel.

  • L'ultima versione ECMAScript abilitata di default (ES2020).

  • Allegato dei commenti.

  • Supporto per JSX, Flow, TypeScript.

  • Supporto per proposte linguistiche sperimentali (accettiamo PR per qualsiasi proposta almeno allo stage-0).

Riconoscimenti

Basato pesantemente su acorn e acorn-jsx, grazie al fantastico lavoro di @RReverser e @marijnh.

API

babelParser.parse(code, [options])

babelParser.parseExpression(code, [options])

parse() analizza il code fornito come un intero programma ECMAScript, mentre parseExpression() cerca di analizzare una singola espressione con un'attenzione alla performance. In caso di dubbio, utilizza .parse().

Opzioni

History
VersionChanges
v7.28.0Added sourceType: "commonjs"
v7.27.0Added allowYieldOutsideFunction
v7.26.0Added startIndex
v7.23.0Added createImportExpressions
v7.21.0Added allowNewTargetOutsideFunction and annexB
v7.16.0Added startColumn
v7.15.0Added attachComment
v7.7.0Added errorRecovery
v7.5.0Added allowUndeclaredExports
v7.2.0Added createParenthesizedExpressions
  • allowImportExportEverywhere: Di default, le dichiarazioni import ed export possono apparire solo al livello superiore del programma. Impostando questa opzione a true sono consentite ovunque sia permessa un'istruzione.

  • allowAwaitOutsideFunction: Di default, l'uso di await è consentito solo all'interno di una funzione asincrona o, quando il plugin topLevelAwait è abilitato, nello scope di livello superiore dei moduli. Imposta a true per accettarlo anche nello scope di livello superiore degli script. Questa opzione è sconsigliata in favore del plugin topLevelAwait.

  • allowYieldOutsideFunction: Di default, l'uso di yield è consentito solo all'interno di una funzione generatrice. Imposta a true per accettarlo anche al livello superiore.

  • allowNewTargetOutsideFunction: Di default, l'uso di new.target non è consentito al di fuori di una funzione o classe. Imposta a true per accettare tale codice.

  • allowReturnOutsideFunction: Di default, un'istruzione return al livello superiore genera un errore. Imposta a true per accettare tale codice.

  • allowSuperOutsideMethod: Di default, l'uso di super non è consentito al di fuori di metodi di classe o oggetti. Imposta a true per accettare tale codice.

  • allowUndeclaredExports: Di default, esportare un identificatore non dichiarato nello scope del modulo corrente genererà un errore. Sebbene questo comportamento sia richiesto dalla specifica dei moduli ECMAScript, il parser di Babel non può anticipare trasformazioni successive nella pipeline dei plugin che potrebbero inserire le dichiarazioni appropriate, quindi talvolta è importante impostare questa opzione a true per evitare che il parser segnali prematuramente esportazioni non dichiarate che verranno aggiunte successivamente.

  • attachComment: Di default, Babel allega i commenti ai nodi AST adiacenti. Quando questa opzione è impostata a false, i commenti non vengono allegati. Può fornire un miglioramento prestazionale fino al 30% quando il codice in input ha molti commenti. @babel/eslint-parser la imposterà automaticamente. Non è consigliato usare attachComment: false con la trasformazione Babel, poiché rimuove tutti i commenti nel codice di output e rende non funzionali annotazioni come /* istanbul ignore next */.

  • annexB: Di default, Babel analizza JavaScript secondo la sintassi dell'Annex B di ECMAScript "Additional ECMAScript Features for Web Browsers". Quando questa opzione è impostata a false, Babel analizzerà la sintassi senza le estensioni specifiche dell'Annex B.

  • createImportExpressions: Per impostazione predefinita, il parser interpreta l'importazione dinamica import() come nodi di espressione di chiamata. Quando questa opzione è impostata su true, vengono invece creati nodi AST ImportExpression. In Babel 8 questa opzione sarà impostata su true per default.

  • createParenthesizedExpressions: Per impostazione predefinita, il parser imposta extra.parenthesized sui nodi di espressione. Quando questa opzione è impostata su true, vengono invece creati nodi AST ParenthesizedExpression.

  • errorRecovery: Per impostazione predefinita, Babel genera sempre un errore quando rileva codice non valido. Quando questa opzione è impostata su true, memorizza l'errore di parsing e tenta di continuare l'analisi del file di input non valido. L'AST risultante avrà una proprietà errors che rappresenta un array di tutti gli errori di parsing. Nota che anche con questa opzione abilitata, @babel/parser potrebbe comunque generare errori per problemi irrecuperabili.

  • plugins: Array contenente i plugin che si desidera abilitare.

  • sourceType: Indica la modalità di parsing del codice. Può essere "script", "commonjs", "module" o "unambiguous". Il default è "script". "unambiguous" fa sì che @babel/parser tenti di dedurre la modalità in base alla presenza di istruzioni ES6 import o export. I file con ES6 imports e exports sono considerati "module", altrimenti "script".

    La modalità "commonjs" indica che il codice dovrebbe essere eseguito in un ambiente CommonJS come Node.js. È compatibile con "script" eccetto per il fatto che return, new.target e dichiarazioni using/await using sono consentite al livello principale.

  • sourceFilename: Collega i nodi AST di output al nome del file sorgente. Utile quando si generano codice e source map da AST di più file di input.

  • startColumn: Per default, il codice analizzato è considerato iniziare dalla riga 1, colonna 0. È possibile specificare un numero di colonna alternativo per l'inizio. Utile per integrazioni con altri strumenti sorgente.

  • startLine: Per default, il codice analizzato è considerato iniziare dalla riga 1, colonna 0. È possibile specificare un numero di riga alternativo per l'inizio. Utile per integrazioni con altri strumenti sorgente.

  • startIndex: Per default, tutti gli indici sorgente iniziano da 0. Con questa opzione è possibile specificare un indice di partenza alternativo. Per garantire indici sorgente AST accurati, questa opzione dovrebbe essere sempre specificata quando startLine è maggiore di 1. Utile per integrazioni con altri strumenti sorgente.

  • strictMode: Per impostazione predefinita, il codice ECMAScript è analizzato in strict mode solo se è presente una direttiva "use strict"; o se il file analizzato è un modulo ECMAScript. Impostare questa opzione su true per analizzare sempre i file in strict mode.

  • ranges: Aggiunge una proprietà range a ogni nodo: [node.start, node.end]

  • tokens: Aggiunge tutti i token analizzati a una proprietà tokens del nodo File

Output

Il parser Babel genera AST secondo il [formato AST di Babel][]. È basato sulla [specifica ESTree][] con le seguenti differenze:

nota

Il plugin estree può annullare queste deviazioni. Usalo solo se stai passando l'AST di Babel ad altri strumenti conformi a ESTree.

L'AST per il codice JSX si basa su Facebook JSX AST.

Semver

Il parser di Babel segue semver nella maggior parte delle situazioni. L'unica cosa da notare è che alcune correzioni di bug relative alla conformità alle specifiche potrebbero essere rilasciate in versioni patch.

Ad esempio: rilasciamo una correzione per un errore precoce su qualcosa come #107 - più esportazioni di default per file. Questa sarebbe considerata una correzione di bug anche se causerebbe il fallimento della build.

Esempio

JavaScript
require("@babel/parser").parse("code", {
// parse in strict mode and allow module declarations
sourceType: "module",

plugins: [
// enable jsx and flow syntax
"jsx",
"flow",
],
});

Plugin

Varie

NameCode Example
estree (repo)n/a

Estensioni del linguaggio

History
VersionChanges
v7.6.0Added v8intrinsic
NameCode Example
flow (repo)var a: string = "";
flowComments (docs)/*:: type Foo = {...}; */
jsx (repo)<a attr="b">{s}</a>
typescript (repo)var a: string = "";
v8intrinsic%DebugPrint(foo);

Proposte ECMAScript

History
VersionChanges
v7.23.0Added sourcePhaseImports, deferredImportEvaluation, optionalChainingAssign
v7.22.0Enabled regexpUnicodeSets by default, added importAttributes
v7.20.0Added explicitResourceManagement, importReflection
v7.17.0Added regexpUnicodeSets, destructuringPrivate, decoratorAutoAccessors
v7.15.0Added hack to the proposal option of pipelineOperator. Moved topLevelAwait, privateIn to Latest ECMAScript features
v7.14.0Added asyncDoExpressions. Moved classProperties, classPrivateProperties, classPrivateMethods, moduleStringNames to Latest ECMAScript features
v7.13.0Added moduleBlocks
v7.12.0Added classStaticBlock, moduleStringNames
v7.11.0Added decimal
v7.10.0Added privateIn
v7.9.0Added recordAndTuple
v7.7.0Added topLevelAwait
v7.4.0Added partialApplication
v7.2.0Added classPrivateMethods
NameCode Example
asyncDoExpressions (proposal)async do { await requestAPI().json() }
decimal (proposal)0.3m
decorators (proposal)
decorators-legacy
@a class A {}
decoratorAutoAccessors (proposal)class Example { @reactive accessor myBool = false; }
deferredImportEvaluation (proposal)import defer * as ns from "dep";
deprecatedImportAssert (⚠️ deprecated, legacy syntax of import attributes)
importAssertions (⚠️ deprecated)
import json from "./foo.json" assert { type: "json" };
destructuringPrivate (proposal)class Example { #x = 1; method() { const { #x: x } = this; } }
doExpressions (proposal)var a = do { if (true) { 'hi'; } };
explicitResourceManagement (proposal)using reader = getReader()
exportDefaultFrom (proposal)export v from "mod"
functionBind (proposal)a::b, ::console.log
functionSent (proposal)function.sent
importReflection (proposal)import module foo from "./foo.wasm";
moduleBlocks (proposal)let m = module { export let y = 1; };
optionalChainingAssign (proposal)x?.prop = 2
partialApplication (proposal)f(?, a)
pipelineOperator (proposal)a |> b
recordAndTuple (proposal)#{x: 1}, #[1, 2]
sourcePhaseImports (proposal)import source x from "./x"
throwExpressions (proposal)() => throw new Error("")

Latest ECMAScript features

The following features are already enabled on the latest version of @babel/parser, and cannot be disabled because they are part of the language. You should enable these features only if you are using an older version.

NameCode Example
asyncGenerators (proposal)async function*() {}, for await (let a of b) {}
bigInt (proposal)100n
classProperties (proposal)class A { b = 1; }
classPrivateProperties (proposal)class A { #b = 1; }
classPrivateMethods (proposal)class A { #c() {} }
classStaticBlock (proposal)class A { static {} }
dynamicImport (proposal)import('./guy').then(a)
exportNamespaceFrom (proposal)export * as ns from "mod"
logicalAssignment (proposal)a &&= b
moduleStringNames (proposal)import { "😄" as smile } from "emoji";
nullishCoalescingOperator (proposal)a ?? b
numericSeparator (proposal)1_000_000
objectRestSpread (proposal)var a = { b, ...c };
optionalCatchBinding (proposal)try {throw 0;} catch{do();}
optionalChaining (proposal)a?.b
privateIn (proposal)#p in obj
regexpUnicodeSets (proposal)/[\p{Decimal_Number}--[0-9]]/v;
topLevelAwait (proposal)await promise in modules
importAttributes (proposal)import json from "./foo.json" with { type: "json" };

Opzioni dei plugin

History
VersionChanges
7.21.0The default behavior of the decorators' decoratorsBeforeExport option is to allow decorators either before or after the export keyword.
7.19.0The syntaxType option of the recordAndTuple plugin defaults to hash; added allowCallParenthesized option for the decorators plugin.
7.17.0Added @@ and ^^ to the topicToken option of the hack pipeline operator
7.16.0Added disallowAmbiguousJSXLike for typescript plugin. Added ^ to the topicToken option of the hack pipeline operators
7.14.0Added dts for typescript plugin

Quando un plugin viene specificato più volte, vengono considerate solo le prime opzioni.

  • decorators:

    • allowCallParenthesized (boolean, valore predefinito true)

      Quando false, non consente i decoratori nella forma @(...)() a favore di @(...()). La proposta dei decoratori allo stage 3 utilizza allowCallParenthesized: false.

    • decoratorsBeforeExport (boolean)

      Per impostazione predefinita, i decoratori sulle classi esportate possono essere posizionati prima o dopo la parola chiave export. Quando questa opzione è impostata, i decoratori saranno consentiti solo nella posizione specificata.

      JavaScript
      // decoratorsBeforeExport: true
      @dec
      export class C {}

      // decoratorsBeforeExport: false
      export @dec class C {}

      Questa opzione è deprecata e verrà rimossa in una versione futura. Il codice che è valido quando questa opzione è impostata esplicitamente a true o false è valido anche quando questa opzione non è impostata.

  • optionalChainingAssign:

    • version (obbligatorio, valori accettati: 2023-07) Questa proposta è ancora allo Stage 1, pertanto è probabile che subirà modifiche incompatibili. È necessario specificare quale versione della proposta si sta utilizzando per garantire che Babel continui a interpretare il codice in modo compatibile.
  • pipelineOperator:

    • proposal (obbligatorio, valori accettati: fsharp, hack, minimal, smart (deprecato)) Esistono diverse proposte per l'operatore pipeline. Questa opzione sceglie quale proposta utilizzare. Consulta plugin-proposal-pipeline-operator per maggiori informazioni, inclusa una tabella comparativa dei comportamenti.
    • topicToken (obbligatorio quando proposal è hack, valori accettati: %, #, ^, @@, ^^) La proposta hack utilizza un segnaposto "topic" nella pipeline. Esistono due scelte diverse per questo segnaposto. Questa opzione determina quale token utilizzare per riferirsi al topic.
  • recordAndTuple:

    • syntaxType (hash o bar, di default hash) Esistono due varianti sintattiche per recordAndTuple. Condividono esattamente la stessa semantica a runtime.
      SyntaxTypeRecord ExampleTuple Example
      "hash"#{ a: 1 }#[1, 2]
      "bar"{| a: 1 |}[|1, 2|]
      Vedi Ergonomics of #{}/#[] per maggiori informazioni.
  • flow:

    • all (boolean, predefinito: false) Alcuni costrutti hanno significati diversi in Flow e in JavaScript vanilla. Ad esempio, foo<T>(x) viene interpretato come chiamata con argomento di tipo in Flow, ma come confronto (foo < T > x) secondo le specifiche ECMAScript. Per impostazione predefinita, babel-parser interpreta questi costrutti ambigui come tipi Flow solo se il file inizia con un pragma // @flow. Impostare questa opzione su true per interpretare sempre i file come se fosse specificato // @flow.
  • typescript

  • importAttributes:

    • deprecatedAssertSyntax (boolean, predefinito: false)

      Se true, consente di interpretare una versione obsoleta degli attributi d'importazione, che utilizzava la keyword assert invece di with.

      Corrisponde alla sintassi originariamente supportata dal plugin parser importAssertions.

Codici di errore

History
VersionChanges
v7.14.0Added error codes

I codici di errore sono utili per gestire gli errori generati da @babel/parser.

Esistono due codici di errore: code e reasonCode.

  • code

    • Classificazione generica degli errori (es. BABEL_PARSER_SYNTAX_ERROR, BABEL_PARSER_SOURCETYPE_MODULE_REQUIRED).
  • reasonCode

    • Classificazione dettagliata degli errori (es. MissingSemicolon, VarRedeclaration).

Esempio di utilizzo dei codici di errore con errorRecovery:

JavaScript
const { parse } = require("@babel/parser");

const ast = parse(`a b`, { errorRecovery: true });

console.log(ast.errors[0].code); // BABEL_PARSER_SYNTAX_ERROR
console.log(ast.errors[0].reasonCode); // MissingSemicolon

Domande frequenti

Il parser di Babel supporterà un sistema di plugin?

Issue precedenti: #1351, #6694.

Attualmente non intendiamo impegnarci nel supportare un'API per plugin o l'ecosistema risultante (c'è già abbastanza lavoro nella manutenzione del sistema di plugin interno di Babel). Non è chiaro come rendere efficace tale API, e limiterebbe la nostra capacità di rifattorizzare e ottimizzare la codebase.

La nostra raccomandazione attuale per chi vuole creare sintassi personalizzate è effettuare un fork del parser.

Per utilizzare il tuo parser personalizzato, puoi aggiungere un plugin alle tue opzioni per richiamare il parser tramite il nome del pacchetto npm o importarlo se stai utilizzando JavaScript,

JavaScript
const parse = require("custom-fork-of-babel-parser-on-npm-here");

module.exports = {
plugins: [
{
parserOverride(code, opts) {
return parse(code, opts);
},
},
],
};