添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
GitHub (opens new window)

# @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 添加 allowNewTargetOutsideFunction annexb
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: false Babel 转换,因为这样做会删除输出代码中的所有注释,并呈现诸如 /* istanbul ignore next */ 非功能性的注释。

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

  • createParenthesizedExpressions:默认情况下,解析器 extra.parenthesized 在表达式节点上设置。当此选项设置为 时 true ParenthesizedExpression 将创建 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 始终以严格模式解析文件。

  • ranges range :向每个节点添加一个属性: [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
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 :

  • syntaxType hash 或者 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 仅当文件以 // @flow pragma 开头时,才将那些不明确的构造解析为 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 .

有两个错误代码, code reasonCode

  • 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/7/2023, 9:06:23 AM