@babel/parser
Парсер Babel (ранее Babylon) — это парсер JavaScript, используемый в Babel.
- По умолчанию включена последняя версия ECMAScript (ES2020).
- Присоединение комментариев.
- Поддержка JSX, Flow, Typescript.
- Поддержка экспериментальных предложений языка (принимаются PR для всего, что, по крайней мере, находится на стадии 0).
Кредиты
Сильно опирается на acorn и acorn-jsx, благодаря замечательной работе @RReverser и @marijnh.
API
babelParser.parse(code, [options])
babelParser.parseExpression(code, [options])
parse() парсит предоставленный code как полную программу ECMAScript, в то время как parseExpression() пытается распарсить отдельное выражение с учётом производительности. В случае сомнений, используйте .parse().
Параметры
История
| Версия | Изменения |
|---|---|
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 парсит JavaScript согласно синтаксису Annex B ECMAScript «Дополнительные функции ECMAScript для веб-браузеров». При установке этого параметра в
false, Babel будет парсить синтаксис без расширений, специфичных для Annex B.createParenthesizedExpressions: По умолчанию парсер устанавливает
extra.parenthesizedна узлах выражений. При установке этого параметра вtrue, вместо этого создаются узлы ASTParenthesizedExpression.errorRecovery: По умолчанию Babel всегда выводит ошибку при обнаружении некорректного кода. При установке этого параметра в
true, он сохранит ошибку разбора и попытается продолжить разбор некорректного файла. Результирующий AST будет иметь свойствоerrors, представляющее массив всех ошибок разбора. Обратите внимание, что даже при включенном этом параметре,@babel/parserможет выдать ошибку для невосстановимых ошибок.plugins: Массив плагинов, которые нужно включить.
sourceType: Указывает режим разбора кода. Может быть одним из
"script","module", или"unambiguous". По умолчанию"script"."unambiguous"позволит @babel/parser попытаться угадать, основываясь на наличии ES6importилиexportинструкций. Файлы с ES6importиexportсчитаются"module", в противном случае они"script".sourceFilename: Связывает узлы выходного AST с их именем файла источника. Полезно при генерации кода и карт исходных данных из AST нескольких входных файлов.
startColumn: По умолчанию парсируемый код обрабатывается так, как будто он начинается с строки 1, столбца 0. Вы можете указать номер столбца для альтернативного начала. Полезно при интеграции с другими инструментами источника.
startLine: По умолчанию парсируемый код обрабатывается так, как будто он начинается с строки 1, столбца 0. Вы можете указать номер строки для альтернативного начала. Полезно при интеграции с другими инструментами источника.
strictMode: По умолчанию ECMAScript-код парсится как строгий только если директива
"use strict";присутствует или если проанализированный файл является ECMAScript-модулем. Установка этого параметра вtrueвсегда будет парсить файлы в строгом режиме.ranges: Добавляет свойство
rangeк каждому узлу:[node.start, node.end]tokens: Добавляет все проанализированные токены в свойство
tokensна узлеFile.
Вывод
Парсер Babel генерирует AST в соответствии с форматом AST Babel. Он основан на спецификации ESTree с такими отличиями:
- Токен «Литерал» заменён на StringLiteral, NumericLiteral, BigIntLiteral, BooleanLiteral, NullLiteral, RegExpLiteral
- Токен «Свойство» заменён на ObjectProperty и ObjectMethod
- MethodDefinition заменён на ClassMethod и ClassPrivateMethod
- PropertyDefinition заменён на ClassProperty и ClassPrivateProperty
- PrivateIdentifier заменён на PrivateName
- Program и BlockStatement содержат дополнительное поле %%%CODE_BLOCK_60%% с Directive и DirectiveLiteral
- ClassMethod, ClassPrivateMethod, ObjectProperty и ObjectMethod свойство значения свойств в FunctionExpression приводится к основному узлу метода.
- ChainExpression заменён на OptionalMemberExpression и OptionalCallExpression
-
ImportExpression заменён на CallExpression, чьё
callee— узел Import.
Теперь существует
estreeплагин, который отменяет эти отклонения
AST для JSX-кода основан на Facebook JSX AST.
Semver
Парсер Babel в большинстве случаев следует semver. Стоит отметить, что некоторые исправления ошибок, соответствующие спецификации, могут быть выпущены с версиями исправления.
Например: мы выпустили исправление для ранней ошибки в случае чего-то вроде #107 — нескольких default экспортов на файл. Это считается исправлением ошибки, даже если оно приведёт к сбою сборки.
Пример
require("@babel/parser").parse("code", {
// parse in strict mode and allow module declarations
sourceType: "module",
plugins: [
// enable jsx and flow syntax
"jsx",
"flow",
],
});
Плагины
Разное
| Название | Пример кода |
|---|---|
estree (репозиторий) |
n/a |
Расширения языка
История
| Версия | Изменения |
|---|---|
v7.6.0 |
Добавлен v8intrinsic
|
| Название | Пример кода |
|---|---|
flow (репозиторий) |
var a: string = ""; |
flowComments (документация) |
/*:: type Foo = {...}; */ |
jsx (репозиторий) |
<a attr="b">{s}</a> |
typescript (репозиторий) |
var a: string = ""; |
v8intrinsic |
%DebugPrint(foo); |
ECMAScript предложения
История
| Версия | Изменения |
|---|---|
v7.20.0 |
Добавлены explicitResourceManagement, importReflection
|
v7.17.0 |
Добавлены regexpUnicodeSets, destructuringPrivate, decoratorAutoAccessors
|
v7.15.0 |
Добавлен hack к параметру proposal pipelineOperator. Перемещены topLevelAwait, privateIn в разделы последних возможностей ECMAScript |
v7.14.0 |
Добавлен asyncDoExpressions. Перемещены classProperties, classPrivateProperties, classPrivateMethods, moduleStringNames в разделы последних возможностей ECMAScript |
v7.13.0 |
Добавлен moduleBlocks
|
v7.12.0 |
Добавлены classStaticBlock, moduleStringNames
|
v7.11.0 |
Добавлен decimal
|
v7.10.0 |
Добавлен privateIn
|
v7.9.0 |
Добавлен recordAndTuple
|
v7.7.0 |
Добавлен topLevelAwait
|
v7.4.0 |
Добавлен partialApplication
|
v7.2.0 |
Добавлен classPrivateMethods
|
| Имя | Пример кода |
|---|---|
asyncDoExpressions (предложение) |
async do { await requestAPI().json() } |
decimal (предложение) |
0.3m |
decorators (предложение) decorators-legacy
|
@a class A {} |
decoratorAutoAccessors (предложение) |
class Example { @reactive accessor myBool = false; } |
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 |
importAssertions (предложение) |
import json from "./foo.json" assert { type: "json" }; |
importReflection (предложение) |
import module foo from "./foo.wasm"; |
moduleBlocks (предложение) |
let m = module { export let y = 1; }; |
partialApplication (предложение) |
f(?, a) |
pipelineOperator (предложение) |
a |> b |
recordAndTuple (предложение) |
#{x: 1}, #[1, 2]
|
regexpUnicodeSets (предложение) |
/[\p{Decimal_Number}--[0-9]]/v; |
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 |
topLevelAwait (предложение) |
await promise в модулях |
Параметры плагинов
История
| Версия | Изменения |
|---|---|
7.21.0 |
По умолчанию, опция decorators' decoratorsBeforeExport позволяет использовать декораторы до или после ключевого слова export. |
7.19.0 |
Опция syntaxType плагина recordAndTuple по умолчанию имеет значение hash; добавлена опция allowCallParenthesized для плагина decorators. |
7.17.0 |
Добавлены @@ и ^^ к опции topicToken оператора конвейера hack. |
7.16.0 |
Добавлен disallowAmbiguousJSXLike для плагина typescript. Добавлена опция ^ для опции topicToken операторов конвейера hack. |
7.14.0 |
Добавлена опция dts для плагина typescript. |
ПРИМЕЧАНИЕ: Если плагин указан несколько раз, учитываются только первые параметры.
-
decorators:-
allowCallParenthesized(boolean, по умолчаниюtrue)При
false, запретить декораторы в форме@(...)()в пользу@(...()). Предложение по декораторам 3-го этапа используетallowCallParenthesized: false. -
decoratorsBeforeExport(boolean)По умолчанию декораторы на экспортируемых классах могут быть размещены перед или после ключевого слова
export. При установке этого параметра декораторы будут разрешены только в указанной позиции.// decoratorsBeforeExport: true @dec export class C {} // decoratorsBeforeExport: false export @dec class C {}⚠️ Этот параметр устарел и будет удален в будущей версии. Код, который валиден при явном установлении этого параметра в
trueилиfalse, также валиден и при отсутствии его установки.
-
-
pipelineOperator:proposal(обязательно, допустимые значения:minimal,fsharp,hack,(устарело)) Существует несколько разных предложений для оператора конвейера. Этот параметр выбирает, какое предложение использовать. Для получения дополнительной информации, включая таблицу сравнения их поведения, см. plugin-proposal-pipeline-operator.smarttopicToken(обязательно, когдаproposalравноhack, допустимые значения:%,#,^,@@,^^) Предложениеhackиспользует «тему» в качестве заполнитель в конвейере. Существует два варианта для этого заполнителя темы. Этот параметр выбирает токен для ссылки на тему.topicToken: "#"несовместим сrecordAndTupleсsyntaxType: "hash". Для получения дополнительной информации см. plugin-proposal-pipeline-operator.
-
recordAndtuple:-
syntaxType(hashилиbar, по умолчаниюhash). Существует два варианта синтаксиса дляrecordAndTuple. Они имеют точно такие же семантику во время выполнения. | Синтаксический тип | Пример записи | Пример кортежа | | --- | --- | --- | |"hash"|#{ a: 1 }|#[1, 2]| |"bar"|{| a: 1 |}|[|1, 2|]| Для получения дополнительной информации см. Эргономика#{}/#[].
-
-
flow:-
all(boolean, по умолчанию:false). Некоторые фрагменты кода имеют разный смысл в Flow и в стандартном JavaScript. Например,foo<T>(x)в Flow парсится как выражение вызова с аргументом типа, а в соответствии со спецификацией ECMAScript — как сравнение (foo < T > x). По умолчаниюbabel-parserпарсит эти неоднозначные конструкции как типы Flow только в том случае, если файл начинается с псевдонима// @flow. Установите этот параметр вtrueдля всегда парсить файлы как если бы// @flowбыл указан.
-
-
typescript-
dts(boolean, по умолчаниюfalse). Этот параметр включит парсинг в контексте TypeScript ambient, где определённый синтаксис имеет другие правила (например, файлы.d.tsи внутри блоковdeclare module). Для получения дополнительной информации об ambient-контекстах см. https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html и https://basarat.gitbook.io/typescript/type-system/intro. -
disallowAmbiguousJSXLike(boolean, по умолчаниюfalse). Даже если плагинjsxне включён, этот параметр запрещает использование синтаксиса, который был бы неоднозначным с JSX (<X> yутверждения типов и<X>() => {}аргументы типов). Он соответствует поведениюtscпри парсинге файлов.mtsи.mjs.
-
Коды ошибок
История
| Версия | Изменения |
|---|---|
v7.14.0 |
Добавлены коды ошибок |
Коды ошибок полезны для обработки ошибок, выброшенных @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
Вопросы и ответы
Будет ли парсер Babel поддерживать систему плагинов?
Предыдущие проблемы: #1351, #6694.
В настоящее время мы не готовы гарантировать поддержку API для плагинов или создаваемой экосистемы (уже достаточно работы по обслуживанию собственной системы плагинов Babel). Неясно, как сделать этот API эффективным, и это ограничит нашу способность к рефакторингу и оптимизации кодовой базы.
В настоящее время мы рекомендуем тем, кто хочет создать собственный синтаксис, форкнуть парсер.
Чтобы использовать свой пользовательский парсер, вы можете добавить плагин в свои параметры, чтобы вызвать парсер через его имя в npm или используя require, если вы используете JavaScript.
const parse = require("custom-fork-of-babel-parser-on-npm-here");
module.exports = {
plugins: [
{
parserOverride(code, opts) {
return parse(code, opts);
},
},
],
};
© 2014-present Sebastian McKenzie
Licensed under the MIT License.
https://babeljs.io/docs/babel-parser/