Spec-Zone.ru › Babel 7

@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, вместо этого создаются узлы AST ParenthesizedExpression.

  • errorRecovery: По умолчанию Babel всегда выводит ошибку при обнаружении некорректного кода. При установке этого параметра в true, он сохранит ошибку разбора и попытается продолжить разбор некорректного файла. Результирующий AST будет иметь свойство errors, представляющее массив всех ошибок разбора. Обратите внимание, что даже при включенном этом параметре, @babel/parser может выдать ошибку для невосстановимых ошибок.

  • plugins: Массив плагинов, которые нужно включить.

  • sourceType: Указывает режим разбора кода. Может быть одним из "script", "module", или "unambiguous". По умолчанию "script". "unambiguous" позволит @babel/parser попытаться угадать, основываясь на наличии ES6 import или export инструкций. Файлы с ES6 import и 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, smart (устарело)) Существует несколько разных предложений для оператора конвейера. Этот параметр выбирает, какое предложение использовать. Для получения дополнительной информации, включая таблицу сравнения их поведения, см. plugin-proposal-pipeline-operator.

    • topicToken (обязательно, когда 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/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API