# @babel/解析器

Babel 解析器(以前称为 Babylon)是Babel 中使用的 JavaScript 解析器。

  • 默认启用最新的 ECMAScript 版本 (ES2020)。
  • 评论附件。
  • 支持 JSX、Flow、Typescript。
  • 支持实验性语言提案(接受任何至少* stage-0 的 PR )。

# 积分

主要基于acorn (opens new window)acorn-jsx (opens new window) ,感谢@RReverser (opens new window)@marijnh (opens new window) 的出色工作。

# 应用程序接口

# babelParser.parse(code,options])[​

# babelParser.parseExpression(code,options])[​

parse()将提供的code作为整个 ECMAScript 程序进行解析,同时 parseExpression()尝试在考虑性能的情况下解析单个表达式。如有疑问,请使用.parse().

Version Changes
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:默认情况下,import声明export只能出现在程序的顶层。将此选项设置为true允许它们在允许语句的任何地方。

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

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

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

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

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

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

  • annexb:默认情况下,Babel 根据ECMAScript 的附件 B “ Additional ECMAScript Features for Web Browsers ” (opens new window) 语法解析 JavaScript。当此选项设置为 时false,Babel 将解析没有特定于 Annex B 的扩展的语法。

  • createParenthesizedExpressions:默认情况下,解析器extra.parenthesized在表达式节点上设置。当此选项设置为 时trueParenthesizedExpression将创建 AST 节点。

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

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

  • sourceType:指示应在其中解析代码的模式。可以是"script""module"或 之一"unambiguous"。默认为"script". "unambiguous"将使@babel/parser 尝试根据 ES6或语句的存在进行猜测。考虑带有 ES6和s的文件,否则为.import``export``import``export``"module"``"script"

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

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

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

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

  • rangesrange:向每个节点添加一个属性:[node.start, node.end]

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

# 输出

Babel 解析器根据Babel AST 格式 (opens new window) 生成 AST 。它基于ESTree 规范 (opens new window) ,但有以下差异:

现在有一个estree插件可以恢复这些偏差

JSX 代码的 AST 基于Facebook JSX AST (opens new window)

# 服务器

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

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

# 示例

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

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

# 插件

# 杂项

姓名 代码示例
estree回购 (opens new window) 不适用

# 语言扩展 (opens new window)

Version Changes
v7.6.0 添加v8intrinsic
姓名 代码示例
flow回购 (opens new window) var a: string = "";
flowComments文档 (opens new window) /*:: type Foo = {...}; */
jsx回购 (opens new window) <a attr="b">{s}</a>
typescript回购 (opens new window) var a: string = "";
v8intrinsic %DebugPrint(foo);

# ECMAScript提案

姓名 代码示例
asyncDoExpressions建议 (opens new window) async do { await requestAPI().json() }
decimal建议 (opens new window) 0.3m
decorators建议 (opens new window)decorators-legacy @a class A {}
decoratorAutoAccessors建议 (opens new window) class Example { @reactive accessor myBool = false; }
destructuringPrivate建议 (opens new window) class Example { #x = 1; method() { const { #x: x } = this; } }
doExpressions建议 (opens new window) var a = do { if (true) { 'hi'; } };
explicitResourceManagement建议 (opens new window) using reader = getReader()
exportDefaultFrom建议 (opens new window) export v from "mod"
functionBind建议 (opens new window) a::b, ::console.log
functionSent建议 (opens new window) function.sent
importAssertions建议 (opens new window) import json from "./foo.json" assert { type: "json" };
importReflection建议 (opens new window) import module foo from "./foo.wasm";
moduleBlocks建议 (opens new window) let m = module { export let y = 1; };
partialApplication建议 (opens new window) f(?, a)
pipelineOperator建议 (opens new window) a |> b
recordAndTuple建议 (opens new window) #{x: 1},#[1, 2]
regexpUnicodeSets建议 (opens new window) /[\p{Decimal_Number}--[0-9]]/v;
throwExpressions建议 (opens new window) () => throw new Error("")

# 最新的 ECMAScript特性

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

姓名 代码示例
asyncGenerators建议 (opens new window) async function*() {},for await (let a of b) {}
bigInt建议 (opens new window) 100n
classProperties建议 (opens new window) class A { b = 1; }
classPrivateProperties建议 (opens new window) class A { #b = 1; }
classPrivateMethods建议 (opens new window) class A { #c() {} }
classStaticBlock建议 (opens new window) class A { static {} }
dynamicImport建议 (opens new window) import('./guy').then(a)
exportNamespaceFrom建议 (opens new window) export * as ns from "mod"
logicalAssignment建议 (opens new window) a &&= b
moduleStringNames建议 (opens new window) import { "😄" as smile } from "emoji";
nullishCoalescingOperator建议 (opens new window) a ?? b
numericSeparator建议 (opens new window) 1_000_000
objectRestSpread建议 (opens new window) var a = { b, ...c };
optionalCatchBinding建议 (opens new window) try {throw 0;} catch{do();}
optionalChaining建议 (opens new window) a?.b
privateIn建议 (opens new window) #p in obj
topLevelAwait建议 (opens new window) await promise在模块中

# 插件选项 (opens new window)

历史| Version | Changes | | :--- | :--- | | | The default behavior of the' option is to allow decorators either before or after the keyword. | | | The option of the plugin defaults to; added option for the plugin. | | | Added and to the option of the pipeline operator | || Added for plugin. Added to the option of the pipeline operators | || Added for plugin |

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

  • decorators:

  • allowCallParenthesized( boolean, 默认为true)

false,禁止@(...)()形式中的装饰器支持@(...())。第 3 阶段装饰器提案使用allowCallParenthesized: false.

  • decoratorsBeforeExport(boolean)

默认情况下,导出类的装饰器可以放在export关键字之前或之后。设置此选项后,装饰器将只允许在指定位置使用。

JavaScript

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

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

⚠️ 此选项已弃用,将在未来版本中删除。明确设置此选项时有效的代码,true或未false设置此选项时也有效的代码。

  • pipelineOperator:

  • proposal(必填,可接受的值:minimal, fsharp, hack,smart(已弃用))对于管道操作员有几种不同的建议。此选项选择要使用的建议。有关更多信息,请参阅plugin-proposal-pipeline-operator (opens new window) ,包括比较它们的行为的表格。

  • topicToken``proposal(在is时需要hack,可接受的值:%, #, ^, @@, ^^hack提案在其管道中使用“主题”占位符。此主题占位符有两种不同的选择。此选项选择使用什么标记来引用主题。 与topicToken: "#"不兼容。有关更多信息,请参阅插件提案管道运算符 (opens new window)recordAndTuple``syntaxType: "hash"

  • recordAndtuple:

  • syntaxTypehash或者bar,默认为hash)有两种语法变体recordAndTuple。它们共享完全相同的运行时语义。| 语法类型 | 记录范例 | 元组示例 | | --- | --- | --- | | "hash"| #{ a: 1 }| #[1, 2]| | "bar"| {| a: 1 |}| [|1, 2|]| 有关详细信息,请参阅/ (opens new window) 的人体工程学#{}#[]

  • flow:

  • all( boolean, default: false) 一些代码在 Flow 和 vanilla JavaScript 中有不同的含义。例如,foo<T>(x)在 Flow 中被解析为带有类型参数的调用表达式,但foo < T > x根据 ECMAScript 规范被解析为比较 ()。默认情况下,babel-parser仅当文件以// @flowpragma 开头时,才将那些不明确的构造解析为 Flow 类型。将此选项设置为true始终像// @flow指定的那样解析文件。

  • typescript

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

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

# 错误代码 (opens new window)

历史| Version | Changes | | :--- | :--- | | ``| Added error codes |

错误代码对于处理@babel/parser.

有两个错误代码,codereasonCode

  • code

  • 错误的粗略分类(例如* BABEL_PARSER_SYNTAX_ERROR, BABEL_PARSER_SOURCETYPE_MODULE_REQUIRED)。

  • reasonCode

  • 错误的详细分类(例如* MissingSemicolon, VarRedeclaration)。

使用错误代码的示例errorRecovery

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 解析器是否支持插件系统 (opens new window)

上期:#1351 (opens new window)#6694 (opens new window)

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

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

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

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

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

Last Updated: 6/14/2023, 8:56:23 AM