本文へスキップ

@babel/parser

Babelパーサー(以前はBabylon)は、Babelで使用されるJavaScriptパーサーです。

  • デフォルトで有効になっている最新のECMAScriptバージョン(ES2020)。
  • コメントの添付。
  • JSX、Flow、TypeScriptのサポート。
  • 実験的な言語提案のサポート(少なくともstage-0のものはPRを受け入れています)。

クレジット

acornacorn-jsxを基にしています。@RReverser@marijnhの素晴らしい仕事に感謝します。

API

babelParser.parse(code, [options])

babelParser.parseExpression(code, [options])

parse()は提供されたcodeをECMAScriptプログラム全体として解析しますが、parseExpression()はパフォーマンスを考慮して単一の式を解析しようとします。 疑問がある場合は、.parse()を使用してください。

オプション

履歴
バージョン変更点
v7.23.0createImportExpressionsを追加
v7.21.0allowNewTargetOutsideFunctionannexbを追加
v7.16.0startColumnを追加
v7.15.0attachCommentを追加
v7.7.0errorRecoveryを追加
v7.5.0allowUndeclaredExportsを追加
v7.2.0createParenthesizedExpressionsを追加
  • **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が自動的に設定します。Babel変換でattachComment: falseを使用することは推奨されません。これは、出力コードのすべてのコメントが削除され、/* istanbul ignore next */などの注釈が無効になるためです。

  • **annexb**: デフォルトでは、BabelはECMAScriptのAnnex B「Webブラウザ用の追加ECMAScript機能」構文に従ってJavaScriptを解析します。このオプションをfalseに設定すると、BabelはAnnex B固有の拡張機能なしで構文を解析します。

  • **createImportExpressions**: デフォルトでは、パーサーは動的インポートimport()を呼び出し式ノードとして解析します。このオプションをtrueに設定すると、代わりにImportExpression ASTノードが作成されます。このオプションはBabel 8ではtrueがデフォルトになります。

  • **createParenthesizedExpressions**: デフォルトでは、パーサーは式ノードにextra.parenthesizedを設定します。このオプションをtrueに設定すると、代わりにParenthesizedExpression ASTノードが作成されます。

  • **errorRecovery**: デフォルトでは、Babelは無効なコードが見つかった場合常にエラーをスローします。このオプションをtrueに設定すると、解析エラーを保存し、無効な入力ファイルの解析を続行しようとします。結果のASTには、すべての解析エラーを表すerrorsプロパティが含まれます。このオプションが有効になっていても、回復不可能なエラーに対して@babel/parserがエラーをスローする可能性があることに注意してください。

  • **plugins**: 有効にするプラグインを含む配列。

  • **sourceType**: コードを解析するモードを示します。"script""module"、または"unambiguous"のいずれかになります。デフォルトは"script"です。"unambiguous"は、@babel/parserがES6のimportまたはexportステートメントの存在に基づいて推測しようとします。ES6のimportexportを含むファイルは"module"と見なされ、それ以外は"script"と見なされます。

  • **sourceFilename**: 出力ASTノードとソースファイル名を関連付けます。複数の入力ファイルのASTからコードとソースマップを生成する場合に役立ちます。

  • **startColumn**: デフォルトでは、解析されたコードは1行目、0列から始まるものとして扱われます。代わりに開始する列番号を指定できます。他のソースツールとの統合に役立ちます。

  • **startLine**: デフォルトでは、解析されたコードは1行目、0列から始まるものとして扱われます。代わりに開始する行番号を指定できます。他のソースツールとの統合に役立ちます。

  • **strictMode**: デフォルトでは、ECMAScriptコードは、"use strict";ディレクティブが存在する場合、または解析されたファイルがECMAScriptモジュールである場合にのみ厳格モードとして解析されます。ファイルを常に厳格モードで解析するには、このオプションをtrueに設定します。

  • **ranges**: 各ノードにrangeプロパティを追加します: [node.start, node.end]

  • **tokens**: 解析されたすべてのトークンをFileノードのtokensプロパティに追加します

出力

Babelパーサーは、Babel AST形式に従ってASTを生成します。これはESTree仕様に基づいており、以下の違いがあります。

ヒント

これらのずれを元に戻すestreeプラグインができました。

JSXコードのASTは、Facebook JSX ASTに基づいています。

Semver

Babelパーサーはほとんどの場合semverに従います。注意すべき唯一の点は、仕様準拠のバグ修正の一部がパッチバージョンでリリースされる可能性があることです。

たとえば、#107(1つのファイルあたりの複数のデフォルトエクスポート)のような早期エラー修正をプッシュします。これは、ビルドが失敗する可能性があっても、バグ修正と見なされます。

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

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

プラグイン

その他

名前コード例
estree (リポジトリ)該当なし

言語拡張

履歴
バージョン変更点
v7.6.0v8intrinsicを追加
名前コード例
flow (リポジトリ)var a: string = "";
flowComments (ドキュメント)/*:: type Foo = {...}; */
jsx (リポジトリ)<a attr="b">{s}</a>
typescript (リポジトリ)var a: string = "";
v8intrinsic%DebugPrint(foo);

ECMAScript 提案

履歴
バージョン変更点
v7.23.0sourcePhaseImportsdeferredImportEvaluationoptionalChainingAssignを追加
v7.22.0regexpUnicodeSetsをデフォルトで有効化、importAttributesを追加
v7.20.0explicitResourceManagementimportReflectionを追加
v7.17.0regexpUnicodeSetsdestructuringPrivatedecoratorAutoAccessorsを追加
v7.15.0pipelineOperatorproposalオプションにhackを追加。topLevelAwaitprivateInを最新のECMAScript機能に移動
v7.14.0asyncDoExpressionsを追加。classPropertiesclassPrivatePropertiesclassPrivateMethodsmoduleStringNamesを最新のECMAScript機能に移動
v7.13.0moduleBlocksを追加
v7.12.0classStaticBlockmoduleStringNamesを追加
v7.11.0decimalを追加
v7.10.0privateInを追加
v7.9.0recordAndTupleを追加
v7.7.0topLevelAwaitを追加
v7.4.0partialApplicationを追加
v7.2.0classPrivateMethodsを追加
名前コード例
asyncDoExpressions (提案)async do { await requestAPI().json() }
decimal (提案)0.3m
decorators (提案)
decorators-legacy
@a class A {}
decoratorAutoAccessors (提案)class Example { @reactive accessor myBool = false; }
deferredImportEvaluation (提案)import defer * as ns from "dep";
destructuringPrivate (提案)class Example { #x = 1; method() { const { #x: x } = this; } }
doExpressions (提案)var a = do { if (true) { 'hi'; } };
explicitResourceManagement (提案)using reader = getReader()
exportDefaultFrom (提案)export v from "mod"
functionBind (提案)a::b::console.log
functionSent (提案)function.sent
importAttributes (提案)
importAssertions (⚠️非推奨)
import json from "./foo.json" with { type: "json" };
importReflection (提案)import module foo from "./foo.wasm";
moduleBlocks (提案)let m = module { export let y = 1; };
optionalChainingAssign (提案)x?.prop = 2
partialApplication (提案)f(?, a)
pipelineOperator (提案)a |> b
recordAndTuple (提案)#{x: 1}#[1, 2]
sourcePhaseImports (提案)import source x from "./x"
throwExpressions (提案)() => throw new Error("")

最新のECMAScript機能

以下の機能は、最新の@babel/parserバージョンで既に有効になっており、言語の一部であるため無効にすることはできません。古いバージョンを使用している場合にのみ、これらの機能を有効にする必要があります。

名前コード例
asyncGenerators (提案)async function*() {}for await (let a of b) {}
bigInt (提案)100n
classProperties (提案)class A { b = 1; }
classPrivateProperties (提案)class A { #b = 1; }
classPrivateMethods (提案)class A { #c() {} }
classStaticBlock (提案)class A { static {} }
dynamicImport (提案)import('./guy').then(a)
exportNamespaceFrom (提案)export * as ns from "mod"
logicalAssignment (提案)a &&= b
moduleStringNames (提案)import { "😄" as smile } from "emoji";
nullishCoalescingOperator (提案)a ?? b
numericSeparator (提案)1_000_000
objectRestSpread (提案)var a = { b, ...c };
optionalCatchBinding (提案)try {throw 0;} catch{do();}
optionalChaining (提案)a?.b
privateIn (提案)#p in obj
regexpUnicodeSets (提案)/[\p{Decimal_Number}--[0-9]]/v;
topLevelAwait (提案)モジュール内のawait promise

プラグインオプション

履歴
バージョン変更点
7.21.0decoratorsdecoratorsBeforeExportオプションのデフォルトの動作は、exportキーワードの前後どちらにもデコレータを許可することです。
7.19.0recordAndTupleプラグインのsyntaxTypeオプションはhashをデフォルト値とします。decoratorsプラグインにallowCallParenthesizedオプションを追加しました。
7.17.0hackパイプライン演算子のtopicTokenオプションに@@^^を追加
7.16.0typescriptプラグインにdisallowAmbiguousJSXLikeを追加。hackパイプライン演算子のtopicTokenオプションに^を追加
7.14.0typescriptプラグインにdtsを追加
注意

プラグインが複数回指定されている場合、最初のオプションのみが考慮されます。

  • importAttributes:

    • deprecatedAssertSyntaxboolean、デフォルトはfalse

      trueの場合、非推奨assertキーワードを使用してインポート属性の解析を許可します。これは、importAssertionsパーサープラグインによって元々サポートされていた構文と一致します。

  • decorators:

    • allowCallParenthesizedboolean、デフォルトはtrue

      falseの場合、@(...())を優先して、@(...)()形式のデコレータを許可しません。ステージ3デコレータ提案では、allowCallParenthesized: falseを使用します。

    • decoratorsBeforeExportboolean

      デフォルトでは、エクスポートされたクラスのデコレータは、exportキーワードの前後どちらにも配置できます。このオプションが設定されている場合、デコレータは指定された位置でのみ許可されます。

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

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

このオプションは非推奨であり、将来のバージョンで削除されます。このオプションが明示的にtrueまたはfalseに設定されている場合に有効なコードは、このオプションが設定されていない場合でも有効です。

  • optionalChainingAssign:

    • version(必須、有効値:2023-07)この提案はまだStage 1であり、破壊的な変更の影響を受ける可能性があります。Babelがコードを互換性のある方法で解析し続けるために、使用している提案のバージョンを指定する必要があります。
  • pipelineOperator:

    • proposal(必須、有効値:minimalfsharphacksmart(非推奨))パイプライン演算子にはいくつかの異なる提案があります。このオプションは、どの提案を使用するかを選択します。plugin-proposal-pipeline-operatorで、動作を比較した表を含む詳細情報をご覧ください。

    • topicTokenproposalhackの場合必須、有効値:%#^@@^^hack提案では、パイプに「トピック」プレースホルダーを使用します。このトピックプレースホルダーには2つの異なる選択肢があります。このオプションは、トピックを参照するために使用するトークンを選択します。topicToken: "#"は、syntaxType: "hash"を持つrecordAndTupleと互換性がありません。plugin-proposal-pipeline-operatorで詳細情報をご覧ください。

  • recordAndTuple:

    • syntaxTypehashまたはbar、デフォルトはhashrecordAndTupleには2つの構文バリアントがあります。これらはまったく同じランタイムセマンティクスを共有します。
      SyntaxTypeレコードの例タプルの例
      "hash"#{ a: 1 }#[1, 2]
      "bar"{| a: 1 |}[|1, 2|]
      詳細については、#{}/#[]の使いやすさを参照してください。
  • flow:

    • allboolean、デフォルト:false)一部のコードは、Flowとvanilla JavaScriptで意味が異なります。たとえば、foo<T>(x)はFlowでは型引数を持つ呼び出し式として解析されますが、ECMAScript仕様に従って比較(foo < T > x)として解析されます。デフォルトでは、babel-parserは、ファイルが// @flowpragmaで始まる場合にのみ、これらの曖昧な構成要素をFlow型として解析します。ファイルを// @flowが指定されているかのように常に解析するには、このオプションをtrueに設定します。
  • typescript

    • dtsboolean、デフォルトfalse)このオプションにより、特定の構文に異なるルールがあるTypeScript環境コンテキスト内での解析が有効になります(.d.tsファイルやdeclare moduleブロック内など)。環境コンテキストの詳細については、https://typescript.dokyumento.jp/docs/handbook/declaration-files/introduction.htmlおよびhttps://basarat.gitbook.io/typescript/type-system/introを参照してください。
    • disallowAmbiguousJSXLikeboolean、デフォルトfalsejsxプラグインが無効になっている場合でも、このオプションはJSXと曖昧になる構文(<X> y型アサーションと<X>() => {}型引数)の使用を許可しません。これは、.mtsおよび.mjsファイルを解析する場合のtscの動作と一致します。

エラーコード

履歴
バージョン変更点
v7.14.0追加されたエラーコード

エラーコードは、@babel/parserによってスローされるエラーを処理するのに役立ちます。

codereasonCodeの2つのエラーコードがあります。

  • code
    • エラーのおおよその分類(例:BABEL_PARSER_SYNTAX_ERRORBABEL_PARSER_SOURCETYPE_MODULE_REQUIRED)。
  • reasonCode
    • エラーの詳細な分類(例:MissingSemicolonVarRedeclaration)。

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パーサーはプラグインシステムをサポートしますか?

以前の問題:#1351#6694

現在、プラグインのAPIや結果として生じるエコシステムのサポートを約束する意思はありません(Babel独自のプラグインシステムのメンテナンスですでに十分な作業があります)。そのAPIを効果的にする方法が明らかではなく、コードベースのリファクタリングと最適化の能力を制限することになります。

独自のカスタム構文を作成したいユーザーには、パーサーをフォークすることをお勧めします。

カスタムパーサーを使用するには、オプションにプラグインを追加して、npmパッケージ名を使用してパーサーを呼び出すか、JavaScriptを使用する場合はそれをrequireします。

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

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