Skip to main content

@babel/parser

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

  • 默认启用最新的 ECMAScript 版本(ES2020)。

    ¥The latest ECMAScript version enabled by default (ES2020).

  • 注释附件。

    ¥Comment attachment.

  • 支持 JSX、Flow、Typescript。

    ¥Support for JSX, Flow, Typescript.

  • 支持实验性语言提案(接受至少 stage-0 的 PR)。

    ¥Support for experimental language proposals (accepting PRs for anything at least stage-0).

致谢

¥Credits

大量基于 acornacorn-jsx,感谢 @RReverser@marijnh 的出色工作。

¥Heavily based on acorn and acorn-jsx, thanks to the awesome work of @RReverser and @marijnh.

API

babelParser.parse(code, [options])

babelParser.parseExpression(code, [options])

parse() 将提供的 code 解析为整个 ECMAScript 程序,而 parseExpression() 尝试解析单个 Expression 并考虑性能。如有疑问,请使用 .parse()

¥parse() parses the provided code as an entire ECMAScript program, while parseExpression() tries to parse a single Expression with performance in mind. When in doubt, use .parse().

选项

¥Options

History
版本变化
v7.26.0已添加 startIndex
v7.23.0已添加 createImportExpressions
v7.21.0添加了 allowNewTargetOutsideFunctionannexB
v7.16.0已添加 startColumn
v7.15.0已添加 attachComment
v7.7.0已添加 errorRecovery
v7.5.0已添加 allowUndeclaredExports
v7.2.0已添加 createParenthesizedExpressions
  • allowImportExportEverywhere:默认情况下,importexport 声明只能出现在程序的顶层。将此选项设置为 true 允许他们在允许语句的任何地方。

    ¥allowImportExportEverywhere: By default, import and export declarations can only appear at a program's top level. Setting this option to true allows them anywhere where a statement is allowed.

  • allowAwaitOutsideFunction:默认情况下,await 只允许在异步函数内部使用,或者在启用 topLevelAwait 插件时,在模块的顶层范围内使用。将此设置为 true 以在脚本的顶层范围内也接受它。不鼓励使用此选项以支持 topLevelAwait 插件。

    ¥allowAwaitOutsideFunction: By default, await use is only allowed inside of an async function or, when the topLevelAwait plugin is enabled, in the top-level scope of modules. Set this to true to also accept it in the top-level scope of scripts. This option is discouraged in favor of topLevelAwait plugin.

  • allowNewTargetOutsideFunction:默认情况下,不允许在函数或类之外使用 new.target。将此设置为 true 以接受此类代码。

    ¥allowNewTargetOutsideFunction: By default, new.target use is not allowed outside of a function or class. Set this to true to accept such code.

  • allowReturnOutsideFunction:默认情况下,顶层的 return 语句会引发错误。将此设置为 true 以接受此类代码。

    ¥allowReturnOutsideFunction: By default, a return statement at the top level raises an error. Set this to true to accept such code.

  • allowSuperOutsideMethod:默认情况下,不允许在类和对象方法之外使用 super。将此设置为 true 以接受此类代码。

    ¥allowSuperOutsideMethod: By default, super use is not allowed outside of class and object methods. Set this to true to accept such code.

  • allowUndeclaredExports:默认情况下,导出未在当前模块作用域内声明的标识符将引发错误。虽然这种行为是 ECMAScript 模块规范所要求的,但 Babel 的解析器无法预期插件管道中稍后可能插入适当声明的转换,因此有时将此选项设置为 true 以防止解析器过早地抗诉未声明的导出稍后会添加。

    ¥allowUndeclaredExports: By default, exporting an identifier that was not declared in the current module scope will raise an error. While this behavior is required by the ECMAScript modules specification, Babel's parser cannot anticipate transforms later in the plugin pipeline that might insert the appropriate declarations, so it is sometimes important to set this option to true to prevent the parser from prematurely complaining about undeclared exports that will be added later.

  • attachComment:默认情况下,Babel 将注释附加到相邻的 AST 节点。当此选项设置为 false 时,不附加注释。当输入代码有很多注释时,它可以提供高达 30% 的性能提升。@babel/eslint-parser 会为你设置。不建议将 attachComment: false 与 Babel 转换一起使用,因为这样做会删除输出代码中的所有注释,并使诸如 /* istanbul ignore next */ 之类的注释不起作用。

    ¥attachComment: By default, Babel attaches comments to adjacent AST nodes. When this option is set to false, comments are not attached. It can provide up to 30% performance improvement when the input code has many comments. @babel/eslint-parser will set it for you. It is not recommended to use attachComment: false with Babel transform, as doing so removes all the comments in output code, and renders annotations such as /* istanbul ignore next */ nonfunctional.

  • 附件 B:默认情况下,Babel 按照 ECMAScript 的附录 B "适用于 Web 浏览器的附加 ECMAScript 功能" 语法解析 JavaScript。当此选项设置为 false 时,Babel 将解析没有特定于 Annex B 的扩展的语法。

    ¥annexB: By default, Babel parses JavaScript according to ECMAScript's Annex B "Additional ECMAScript Features for Web Browsers" syntax. When this option is set to false, Babel will parse syntax without the extensions specific to Annex B.

  • 创建导入表达式:默认情况下,解析器将动态导入 import() 解析为调用表达式节点。当此选项设置为 true 时,会改为创建 ImportExpression AST 节点。该选项在 Babel 8 中默认为 true

    ¥createImportExpressions: By default, the parser parses dynamic import import() as call expression nodes. When this option is set to true, ImportExpression AST nodes are created instead. This option will default to true in Babel 8.

  • 创建括号表达式:默认情况下,解析器在表达式节点上设置 extra.parenthesized。当此选项设置为 true 时,会改为创建 ParenthesizedExpression AST 节点。

    ¥createParenthesizedExpressions: By default, the parser sets extra.parenthesized on the expression nodes. When this option is set to true, ParenthesizedExpression AST nodes are created instead.

  • 错误恢复:默认情况下,Babel 在发现一些无效代码时总是会抛出错误。当此选项设置为 true 时,它将存储解析错误并尝试继续解析无效的输入文件。生成的 AST 将具有 errors 属性,表示所有解析错误的数组。请注意,即使启用此选项,@babel/parser 也可能抛出不可恢复的错误。

    ¥errorRecovery: By default, Babel always throws an error when it finds some invalid code. When this option is set to true, it will store the parsing error and try to continue parsing the invalid input file. The resulting AST will have an errors property representing an array of all the parsing errors. Note that even when this option is enabled, @babel/parser could throw for unrecoverable errors.

  • 插件:包含要启用的插件的数组。

    ¥plugins: Array containing the plugins that you want to enable.

  • 来源类型:指示代码应该被解析的模式。可以是 "script""module""unambiguous" 之一。默认为 "script""unambiguous" 将使@babel/parser 尝试根据 ES6 importexport 语句的存在进行猜测。具有 ES6 importexport 的文件被视为 "module",否则为 "script"

    ¥sourceType: Indicate the mode the code should be parsed in. Can be one of "script", "module", or "unambiguous". Defaults to "script". "unambiguous" will make @babel/parser attempt to guess, based on the presence of ES6 import or export statements. Files with ES6 imports and exports are considered "module" and are otherwise "script".

  • 源文件名:将输出 AST 节点与其源文件名相关联。从多个输入文件的 AST 生成代码和源映射时很有用。

    ¥sourceFilename: Correlate output AST nodes with their source filename. Useful when generating code and source maps from the ASTs of multiple input files.

  • 起始列:默认情况下,解析后的代码被视为从第 1 行第 0 列开始。你可以提供一个列号以替代开始。对于与其他源工具的集成很有用。

    ¥startColumn: By default, the parsed code is treated as if it starts from line 1, column 0. You can provide a column number to alternatively start with. Useful for integration with other source tools.

  • 起始行:默认情况下,解析后的代码被视为从第 1 行第 0 列开始。你可以提供一个行号以替代开始。对于与其他源工具的集成很有用。

    ¥startLine: By default, the parsed code is treated as if it starts from line 1, column 0. You can provide a line number to alternatively start with. Useful for integration with other source tools.

  • startIndex:默认情况下,所有源索引都从 0 开始。使用此选项,你可以提供备用起始索引。为确保准确的 AST 源索引,当 startLine 大于 1 时应始终提供此选项。对于与其他源工具的集成很有用。

    ¥startIndex: By default, all source indexes start from 0. With this option you can provide an alternative start index. To ensure accurate AST source indexes this option should always be provided when startLine is greater than 1. Useful for integration with other source tools.

  • 严格模式:默认情况下,仅当存在 "use strict"; 指令或解析的文件是 ECMAScript 模块时,ECMAScript 代码才会被解析为严格的。将此选项设置为 true 以始终以严格模式解析文件。

    ¥strictMode: By default, ECMAScript code is parsed as strict only if a "use strict"; directive is present or if the parsed file is an ECMAScript module. Set this option to true to always parse files in strict mode.

  • 范围:为每个节点添加一个 range 属性:[node.start, node.end]

    ¥ranges: Adds a range property to each node: [node.start, node.end]

  • 令牌:将所有已解析的标记添加到 File 节点上的 tokens 属性

    ¥tokens: Adds all parsed tokens to a tokens property on the File node

输出

¥Output

Babel 解析器根据 Babel AST 格式 生成 AST。它基于 ES 树规范,但有以下差异:

¥The Babel parser generates AST according to Babel AST format. It is based on ESTree spec with the following deviations:

注意

estree 插件可以恢复这些偏差。仅当你将 Babel AST 传递给其他符合 ESTree 的工具时才使用它。

¥The estree plugin can revert these deviations. Use it only if you are passing Babel AST to other ESTree-compliant tools.

JSX 代码的 AST 基于 Facebook JSX AST

¥AST for JSX code is based on Facebook JSX AST.

服务器

¥Semver

Babel Parser 在大多数情况下都遵循 semver。唯一需要注意的是,一些符合规范的错误修复可能会在补丁版本下发布。

¥The Babel Parser follows semver in most situations. The only thing to note is that some spec-compliancy bug fixes may be released under patch versions.

例如:我们修复了 #107 等早期错误 - 每个文件有多个默认导出。这将被视为一个错误修复,即使它会导致构建失败。

¥For example: We push a fix to early error on something like #107 - multiple default exports per file. That would be considered a bug fix even though it would cause a build to fail.

示例

¥Example

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

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

插件

¥Plugins

各种各样的

¥Miscellaneous

NameCode Example
estree (repo)n/a

语言扩展

¥Language extensions

History
版本变化
v7.6.0已添加 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);

ECMAScript proposals

History
版本变化
v7.23.0添加了 sourcePhaseImportsdeferredImportEvaluationoptionalChainingAssign
v7.22.0默认启用 regexpUnicodeSets,添加 importAttributes
v7.20.0已添加 explicitResourceManagementimportReflection
v7.17.0添加了 regexpUnicodeSetsdestructuringPrivatedecoratorAutoAccessors
v7.15.0hack 添加到 pipelineOperatorproposal 选项。将 topLevelAwaitprivateIn 移动到最新的 ECMAScript 特性
v7.14.0添加了 asyncDoExpressions。将 classPropertiesclassPrivatePropertiesclassPrivateMethodsmoduleStringNames 移动到最新的 ECMAScript 功能
v7.13.0已添加 moduleBlocks
v7.12.0已添加 classStaticBlockmoduleStringNames
v7.11.0已添加 decimal
v7.10.0已添加 privateIn
v7.9.0已添加 recordAndTuple
v7.7.0已添加 topLevelAwait
v7.4.0已添加 partialApplication
v7.2.0已添加 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 (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("")

最新的 ECMAScript 特性

¥Latest ECMAScript features

以下功能已在最新版本的 @babel/parser 上启用,并且无法禁用,因为它们是语言的一部分。只有在使用旧版本时才应启用这些功能。

¥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" };

插件选项

¥Plugins options

History
版本变化
7.21.0decorators' decoratorsBeforeExport 选项的默认行为是允许在 export 关键字之前或之后使用装饰器。
7.19.0recordAndTuple 插件的 syntaxType 选项默认为 hash;为 decorators 插件添加了 allowCallParenthesized 选项。
7.17.0hack 管道操作器的 topicToken 选项中添加了 @@^^
7.16.0typescript 插件添加了 disallowAmbiguousJSXLike。将 ^ 添加到 hack 管道运算符的 topicToken 选项
7.14.0typescript 插件添加了 dts
注意

当一个插件被多次指定时,只考虑第一个选项。

¥When a plugin is specified multiple times, only the first options are considered.

  • decorators

    • allowCallParenthesized(boolean, 默认为 true)

      ¥allowCallParenthesized (boolean, defaults to true)

      false 时,不允许 @(...)() 形式的装饰器支持 @(...())。第 3 阶段装饰器提案使用 allowCallParenthesized: false

      ¥When false, disallow decorators in the @(...)() form in favor of @(...()). The stage 3 decorators proposal uses allowCallParenthesized: false.

    • decoratorsBeforeExport(boolean)

      By default decorators on exported classes can be placed either before or after the `export` keyword. When this option is set, decorators will only be allowed in the specified position.

      ```js title="JavaScript"
      // decoratorsBeforeExport: true
      @dec
      export class C {}

      // decoratorsBeforeExport: false
      export @dec class C {}
      ```
提醒
This option is deprecated and will be removed in a future version. Code that is valid when this option is explicitly set to `true` or `false` is also valid when this option is not set.
  • optionalChainingAssign

    • version(必需,接受的值:2023-07)该提案仍处于第一阶段,因此它很可能会受到重大变更的影响。你必须指定你正在使用的提案版本,以确保 Babel 继续以兼容的方式解析你的代码。

      ¥version (required, accepted values: 2023-07) This proposal is still at Stage 1, and thus it's likely that it will be affected by breaking changes. You must specify which version of the proposal you are using to ensure that Babel will continue to parse your code in a compatible way.

  • pipelineOperator

  • proposal(必需,可接受的值:fsharphackminimalsmart(已弃用)) 对于管道运算符有几种不同的建议。此选项选择要使用的建议。有关更多信息,请参阅 plugin-proposal-pipeline-operator,包括比较它们的行为的表格。

    ¥proposal (required, accepted values: fsharp, hack, minimal, smart (deprecated)) There are several different proposals for the pipeline operator. This option chooses which proposal to use. See plugin-proposal-pipeline-operator for more information, including a table comparing their behavior.

  • topicToken(当 proposalhack 时必需,可接受的值:%#^@@^^hack 提案在其管道中使用“主题”占位符。此主题占位符有两种不同的选择。此选项选择使用什么标记来引用主题。topicToken: "#"recordAndTuplesyntaxType: "hash" 不兼容。有关详细信息,请参阅 plugin-proposal-pipeline-operator

    ¥topicToken (required when proposal is hack, accepted values: %, #, ^, @@, ^^) The hack proposal uses a “topic” placeholder in its pipe. There are two different choices for this topic placeholder. This option chooses what token to use to refer to the topic. topicToken: "#" is incompatible with recordAndTuple with syntaxType: "hash". See plugin-proposal-pipeline-operator for more information.

  • recordAndTuple

    • syntaxTypehashbar,默认为 hashrecordAndTuple 有两种语法变体。它们共享完全相同的运行时语义。

      ¥syntaxType (hash or bar, defaults to hash) There are two syntax variants for recordAndTuple. They share exactly same runtime semantics.

SyntaxTypeRecord ExampleTuple Example
"hash"#{ a: 1 }#[1, 2]
"bar"{| a: 1 |}[|1, 2|]
See Ergonomics of #{}/#[] for more information.
  • flow

    • allboolean,默认值:false)某些代码在 Flow 和普通 JavaScript 中具有不同的含义。例如,foo<T>(x) 在 Flow 中被解析为带有类型参数的调用表达式,但根据 ECMAScript 规范作为比较 (foo < T > x)。默认情况下,仅当文件以 // @flow pragma 开头时,babel-parser 才会将这些模棱两可的结构解析为 Flow 类型。将此选项设置为 true 以始终像指定 // @flow 一样解析文件。

      ¥all (boolean, default: false) Some code has different meaning in Flow and in vanilla JavaScript. For example, foo<T>(x) is parsed as a call expression with a type argument in Flow, but as a comparison (foo < T > x) accordingly to the ECMAScript specification. By default, babel-parser parses those ambiguous constructs as Flow types only if the file starts with a // @flow pragma. Set this option to true to always parse files as if // @flow was specified.

  • typescript

    • dtsboolean,默认 false)此选项将在 TypeScript 环境上下文中启用解析,其中某些语法具有不同的规则(如 .d.ts 文件和 declare module 块内)。有关环境上下文的更多信息,请参阅 https://ts.nodejs.cn/docs/handbook/declaration-files/introduction.htmlhttps://basarat.gitbook.io/typescript/type-system/intro

      ¥dts (boolean, default false) This option will enable parsing within a TypeScript ambient context, where certain syntax have different rules (like .d.ts files and inside declare module blocks). Please see https://ts.nodejs.cn/docs/handbook/declaration-files/introduction.html and https://basarat.gitbook.io/typescript/type-system/intro for more information about ambient contexts.

    • disallowAmbiguousJSXLikeboolean,默认 false)即使未启用 jsx 插件,此选项也不允许使用与 JSX 有歧义的语法(<X> y 类型断言和 <X>() => {} 类型参数)。它在解析 .mts.mjs 文件时匹配 tsc 行为。

      ¥disallowAmbiguousJSXLike (boolean, default false) Even when the jsx plugin is not enabled, this option disallows using syntax that would be ambiguous with JSX (<X> y type assertions and <X>() => {} type arguments). It matches the tsc behavior when parsing .mts and .mjs files.

  • importAttributes

    • deprecatedAssertSyntax(boolean, 默认为 false)

      ¥deprecatedAssertSyntax (boolean, defaults to false)

      当使用 true 时,允许解析旧版本的导入属性,该版本使用 assert 关键字而不是 with

      ¥When true, allow parsing an old version of the import attributes, which used the assert keyword instead of with.

This matches the syntax originally supported by the `importAssertions` parser plugin.

:::

错误代码

¥Error codes

History
版本变化
v7.14.0添加错误代码

错误代码对于处理 @babel/parser 抛出的错误很有用。

¥Error codes are useful for handling the errors thrown by @babel/parser.

有两个错误代码,codereasonCode

¥There are two error codes, code and reasonCode.

  • code

    • 错误的粗略分类(例如 BABEL_PARSER_SYNTAX_ERRORBABEL_PARSER_SOURCETYPE_MODULE_REQUIRED)。

      ¥Rough classification of errors (e.g. BABEL_PARSER_SYNTAX_ERROR, BABEL_PARSER_SOURCETYPE_MODULE_REQUIRED).

  • reasonCode

    • 错误的详细分类(例如 MissingSemicolonVarRedeclaration)。

      ¥Detailed classification of errors (e.g. MissingSemicolon, VarRedeclaration).

使用 errorRecovery 的错误代码示例:

¥Example of using error codes with 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

常见问题

¥FAQ

Babel 解析器会支持插件系统吗?

¥Will the Babel parser support a plugin system?

以前的问题:#1351#6694

¥Previous issues: #1351, #6694.

我们目前不愿意保证支持插件的 API 或由此产生的生态系统(已经有足够的工作来维护 Babel 自己的插件系统)。目前尚不清楚如何使该 API 有效,这将限制我们重构和优化代码库的能力。

¥We currently aren't willing to commit to supporting the API for plugins or the resulting ecosystem (there is already enough work maintaining Babel's own plugin system). It's not clear how to make that API effective, and it would limit our ability to refactor and optimize the codebase.

对于那些想要创建自己的自定义语法的用户,我们目前的建议是让用户复刻解析器。

¥Our current recommendation for those that want to create their own custom syntax is for users to fork the parser.

要使用你的自定义解析器,你可以向你的 选项 添加一个插件,以通过其 npm 包名称调用解析器,或者如果使用 JavaScript,则需要它,

¥To consume your custom parser, you can add a plugin to your options to call the parser via its npm package name or require it if using JavaScript,

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

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