对Babel的研究2

 

      插件选项

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

  decorators

         decoratorsBeforeExportboolean

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

 pipelineOperator

  proposal(必需的,可接受的值:minimalsmart)管道操作员有不同的建议。此选项允许选择使用哪个。请参阅管道提案(|>)发生了什么?了解更多信息。

flow

     allboolean,默认值false:)在Flow和原始JavaScript中,某些代码具有不同的含义。例如,foo<T>(x)在Flow中将解析为带有类型参数的调用表达式,但将其解析为与foo < T > xECMAScript规范相对应的比较()。默认情况下,babel-parser仅当文件以// @flow编译指示开头时,才将这些歧义结构解析为Flow类型将此选项设置true为始终解析文件,就像// @flow指定的一样。

常问问题

Babel解析器是否支持插件系统?

先前的问题:#1351#6694

我们目前不愿意为插件或由此产生的生态系统提供支持的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); }, }] }

@babel/core

   var babel = require("@babel/core"); import { transform } from "@babel/core"; import * as babel from "@babel/core";

所有转换将使用本地配置文件

转变

babel.transform(代码:字符串,选项?:对象,回调:功能)

转换传入的code使用具有生成的代码,源映射和AST的对象调用回调。

babel.transform(code, options, function(err, result) { result; // => { code, map, ast } });

babel.transform("code();", options, function(err, result) { result.code; result.map; result.ast; });

兼容说明:

在Babel 6中,此方法是同步的,transformSync并不存在。为了向后兼容,如果未提供回调,则此函数将同步运行。如果您从Babel 7开始并且需要同步行为,请使用,transformSync因为此向后兼容可能会在Babel的未来主要版本中删除。

transformSync

babel.transformSync(代码:字符串,选项?:对象)

转换传入的code返回带有生成的代码,源映射和AST的对象。

babel.transformSync(code, options) // => { code, map, ast }

var result = babel.transformSync("code();", options); result.code; result.map; result.ast;

transformAsync

babel.transformAsync(代码:字符串,选项?:对象)

转换传入的code使用生成的代码,源映射和AST返回对象的承诺。

babel.transformAsync(code, options) // => Promise<{ code, map, ast }>

babel.transformAsync("code();", options).then(result => { result.code; result.map; result.ast; });

transformFile

babel.transformFile(文件名:字符串,选项?:对象,回调:功能)

异步转换文件的全部内容。

babel.transformFile(filename, options, callback)

babel.transformFile("filename.js", options, function (err, result) { result; // => { code, map, ast } });

transformFileSync

babel.transformFileSync(文件名:字符串,选项?:对象)

的同步版本babel.transformFile返回的转换后的内容filename

babel.transformFileSync(filename, options) // => { code, map, ast }

babel.transformFileSync("filename.js", options).code;

transformFileAsync

babel.transformFileAsync(文件名:字符串,选项?:对象)

的无极版babel.transformFile传回的已转换内容的Promise filename

babel.transformFileAsync(filename, options) // => Promise<{ code, map, ast }>

babel.transformFileAsync("filename.js", options).then(result => { result.code; });

transformFromAst

babel.transformFromAst(ast:Object,code ?:字符串,选项?:Object,回调:函数):FileNode | 空值

给定AST,对其进行转换。

const sourceCode = "if (true) return;"; const parsedAst = babel.parse(sourceCode, { parserOpts: { allowReturnOutsideFunction: true } }); babel.transformFromAst(parsedAst, sourceCode, options, function(err, result) { const { code, map, ast } = result; });

兼容说明:

在Babel 6中,此方法是同步的,transformFromAstSync并不存在。为了向后兼容,如果未提供回调,则此函数将同步运行。如果您从Babel 7开始并且需要同步行为,请使用,transformFromAstSync因为此向后兼容可能会在Babel的未来主要版本中删除。

transformFromAstSync

babel.transformFromAstSync(ast:Object,code ?: string,options?:Object)

给定AST,对其进行转换。

const sourceCode = "if (true) return;"; const parsedAst = babel.parse(sourceCode, { parserOpts: { allowReturnOutsideFunction: true } }); const { code, map, ast } = babel.transformFromAstSync(parsedAst, sourceCode, options);

给定AST,对其进行转换。

const sourceCode = "if (true) return;"; babel.parseAsync(sourceCode, { parserOpts: { allowReturnOutsideFunction: true } }) .then(parsedAst => { return babel.transformFromAstAsync(parsedAst, sourceCode, options); }) .then(({ code, map, ast }) => { // ... });

解析

babel.parse(代码:字符串,选项?:对象,回调:功能)

给定一些代码,使用Babel的标准行为对其进行解析。将加载引用的预设和插件,以便自动启用可选的语法插件。

兼容说明:

在Babel 7的早期Beta中,此方法是同步的,parseSync并不存在。为了向后兼容,如果未提供回调,则此函数将同步运行。如果您从Babel 7稳定版开始并且需要同步行为,请使用parseSync此版本,因为在Babel的未来主要版本中可能会删除此向后兼容。

parseSync

babel.parseSync(代码:字符串,选项?:对象)

返回AST。

给定一些代码,使用Babel的标准行为对其进行解析。将加载引用的预设和插件,以便自动启用可选的语法插件。

parseAsync

babel.parseAsync(code:string,options?:Object)

返回AST的承诺。

给定一些代码,使用Babel的标准行为对其进行解析。将加载引用的预设和插件,以便自动启用可选的语法插件。

进阶API

许多包装Babel的系统都喜欢自动注入插件和预设,或覆盖选项。为了实现此目标,Babel公开了一些功能,这些功能有助于部分加载配置而不进行转换。

loadOptions

babel.loadOptions(options?:Object)

完全解析Babel的选项,产生一个options对象,其中:

  • opts.pluginsPlugin实例的完整列表
  • opts.presets为空,所有预设均被展平为opts
  • 它可以安全地传递回Babel。字段"babelrc"已设置为, false这样以后对Babel的调用将不会再次尝试加载配置文件。

Plugin实例并不意味着可以直接进行操作,但是调用者通常会将其序列化为optsJSON,以将其用作表示Babel收到的选项的缓存键。不能保证100%正确地对此进行缓存,但这是我们目前拥有的最好方法。

loadPartialConfig

babel.loadPartialConfig(options?:Object):PartialConfig

为了使系统能够轻松地操纵和验证用户的配置,此功能可解析插件和预设,并且不再进行任何操作。期望的是,呼叫者将采用配置文件.options,在他们认为合适的情况下对其进行操作,然后将其再次传递回Babel。

  • babelrc: string | void文件相对配置文件的路径(如果有)。
  • babelignore: string | void.babelignore文件路径(如果有的话)。
  • config: string | void项目范围的配置文件的路径(如果有的话)。
  • options: ValidatedOptions -部分解决的选项,可以对其进行操作并再次传递回Babel。
    • plugins: Array<ConfigItem> - 见下文。
    • presets: Array<ConfigItem> - 见下文。
    • 它可以安全地传递回Babel。像这样的选项"babelrc"已设置为false,以便以后对Babel的调用不会再次尝试加载配置文件。
  • hasFilesystemConfig(): boolean -检查解析的配置是否从文件系统加载了任何设置。

ConfigItem实例公开属性以对​​值进行内部检查,但每个项目都应视为不可变的。如果需要更改,则应从列表中删除该项目,并用常规的Babel配置值或用创建的替换项目替换babel.createConfigItem有关该ConfigItem字段的信息,请参见该函数

createConfigItem

babel.createConfigItem(值:字符串| {} |函数| [字符串| {} |函数,{} |无效],{目录名?:字符串,类型?:“预设” |“插件”}):ConfigItem

允许构建工具预先创建和缓存配置项。如果给定插件多次调用此函数,Babel将多次调用插件自身的函数。如果您有明确的预期插件集和要注入的预设,则建议预先构造配置项。

ConfigItem 类型

每个ConfigItem公开了Babel知道的所有信息。这些字段是:

  • value: {} | Function -插件的解析值。
  • options: {} | void -将选项对象传递给插件。
  • dirname: string -选项相对的路径。
  • name: string | void -用户为插件实例指定的名称,例如 plugins: [ ['env', {}, 'my-env'] ]
  • file: Object | void -如果Babel知道,则有关插件文件的信息。
    • request: string -用户请求的文件,例如 "@babel/env"
    • resolved: string -解析文件的完整路径,例如 "/tmp/node_modules/@babel/preset-env/lib/index.js"

DEFAULT_EXTENSIONS

babel.DEFAULT_EXTENSIONS:ReadonlyArray

babel支持的默认扩展列表(“ .js”,“。jsx”,“。es6”,“。es”,“。mjs”)。@ babel / register和@ babel / cli使用此列表来确定哪些文件需要转译。无法扩展此列表,但是@ babel / cli确实提供了使用来支持其他扩展的方法--extensions

@babel/generator

安装

npm install --save-dev @babel/generator

用法

import {parse} from '@babel/parser'; import generate from '@babel/generator'; const code = 'class Example {}'; const ast = parse(code); const output = generate(ast, { /* options */ }, code);

选件

格式化输出的选项:

名称类型默认描述
assistantCommentBefore   在输出文件开始处添加为块注释的可选字符串
辅助评论后   在输出文件末尾添加为块注释的可选字符串
应该打印评论 功能 opts.comments 接受注释(作为字符串)并返回true注释是否应包含在输出中的函数默认情况下,所有注释,如果opts.commentstrue,或者opts.minifiedfalse和注释包含@preserve@license
keepLines 布尔值 false 尝试在输出代码中使用与源代码中相同的行号(有助于保留堆栈跟踪)
keepFunctionParens 布尔值 false 保留函数表达式周围的括号(可用于更改引擎的解析行为)
注释 布尔值 true 输出中是否应包含注释
紧凑 布尔值或 'auto' opts.minified 设置为true避免添加空格以进行格式化
缩小 布尔值 false 是否应缩小输出
简洁 布尔值 false 设置为true减少空白(但不超过opts.compact
文件名   用于警告消息
jsonCompatibleStrings 布尔值 false 设置为true以jsesc与“ json” 一起运行:true以打印“ u00A9”与“©”;

源地图的选项:

名称类型默认描述
sourceMaps 布尔值 false 启用生成源地图
sourceRoot   源映射中所有相对URL的根
sourceFileName   源代码的文件名(即code参数中的代码)。仅当code为字符串时才使用

来自多个来源的AST

在大多数情况下,Babel会将输入文件与输出文件进行1:1转换。但是,您可能正在处理由多个源(包括JS文件,模板等)构造的AST。如果是这种情况,并且您希望源映射反映正确的源,则需要将对象传递给generate作为code参数。键应该是源文件名,值应该是源内容。

这是一个可能看起来像的例子:

import {parse} from '@babel/parser'; import generate from '@babel/generator'; const a = 'var a = 1;'; const b = 'var b = 2;'; const astA = parse(a, { sourceFilename: 'a.js' }); const astB = parse(b, { sourceFilename: 'b.js' }); const ast = { type: 'Program', body: [].concat(astA.program.body, astB.program.body) }; const { code, map } = generate(ast, { sourceMaps: true }, { 'a.js': a, 'b.js': b }); // Sourcemap will point to both a.js and b.js where appropriate.

@babel/code-frame

npm install --save-dev @babel/code-frame

Usage

import { codeFrameColumns } from '@babel/code-frame'; const rawLines = `class Foo { constructor() }`; const location = { start: { line: 2, column: 16 } }; const result = codeFrameColumns(rawLines, location, { /* options */ }); console.log(result);

1 | class Foo { > 2 | constructor() | ^ 3 | }

如果列号未知,则可以省略。

您还可以在中传递end哈希值location

import { codeFrameColumns } from '@babel/code-frame'; const rawLines = `class Foo { constructor() { console.log("hello"); } }`; const location = { start: { line: 2, column: 17 }, end: { line: 4, column: 3 } }; const result = codeFrameColumns(rawLines, location, { /* options */ }); console.log(result);

1 | class Foo { > 2 | constructor() { | ^ > 3 | console.log("hello"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ > 4 | } | ^^^ 5 | };

选件

highlightCode

boolean,默认为false

切换突出显示代码的语法作为终端的JavaScript。

linesAbove

number,默认为2

调整行数以在错误上方显示。

linesBelow

number,默认为3

调整行数以在错误下方显示。

forceColor

boolean,默认为false

启用它以强制语法将代码突出显示为JavaScript(对于非终端);覆盖highlightCode

message

string,否则什么也没有

传递要在代码中突出显示的位置旁边内联显示的字符串(如果可能)。如果无法内联放置,它将被放置在代码框上方。

1 | class Foo { > 2 | constructor() | ^ Missing { 3 | };

从以前的版本升级

在版本7之前,此模块公开的唯一API是用于单行和可选的列指针。现在,旧的API将记录弃用警告。

新的API带有一个location对象,类似于AST中提供对象。

这是已弃用(但仍可用)的API的示例:

import codeFrame from '@babel/code-frame'; const rawLines = `class Foo { constructor() }`; const lineNumber = 2; const colNumber = 16; const result = codeFrame(rawLines, lineNumber, colNumber, { /* options */ }); console.log(result);

要使用新的API获得相同的突出显示,请执行以下操作:

import { codeFrameColumns } from '@babel/code-frame'; const rawLines = `class Foo { constructor() { console.log("hello"); } }`; const location = { start: { line: 2, column: 16 } }; const result = codeFrameColumns(rawLines, location, { /* options */ }); console.log(result);

@babel/helpers

npm install --save-dev @babel/helpers

import * as helpers from '@babel/helpers'; import * as t from '@babel/types'; const typeofHelper = helpers.get('typeof'); t.isExpressionStatement(typeofHelper); // true

Inside a plugin:

export default { visitor: { UnaryExpression(path) { // The .addHelper function adds, if needed, the helper to the file // and returns an expression which references the helper const typeofHelper = this.addHelper("typeof"); t.isExpression(typeofHelper); // true } };

定义助手

注意:此软件包仅供该存储库中包含的软件包使用。当前,第三方插件无法定义助手。

帮助程序在src/helpers.js文件中定义,它们必须是遵循以下准则的有效模块:

  • 它们必须具有默认导出,这是它们的入口点。
  • 他们可以仅通过使用默认导入来导入其他帮助程序。
  • 他们不能命名出口。

helpers.customHelper = defineHelper(` import dep from "dependency"; const foo = 2; export default function getFooTimesDepPlusX(x) { return foo * dep() + x; } `);

@ babel /运行时

是一个包含Babel模块化运行时帮助程序和的版本的库

npm install --save @babel/runtime

用法

它打算dependency与Babel插件一起用作运行时@babel/plugin-transform-runtime

为什么

有时Babel可能会在输出中注入一些跨文件相同的代码,因此有可能被重用。

例如,使用类转换(无松散模式):

class Circle {}

function _classCallCheck(instance, Constructor) { //... } var Circle = function Circle() { _classCallCheck(this, Circle); };

这意味着每个包含类的文件都将具有_classCallCheck每次重复功能。

使用@babel/plugin-transform-runtime,它将替换对@babel/runtime版本的功能的引用

var _classCallCheck = require("@babel/runtime/helpers/classCallCheck"); var Circle = function Circle() { _classCallCheck(this, Circle); };

@babel/runtime 只是包含以模块化方式实现功能的程序包。

@ babel /模板

在计算机科学中,这被称为准引用的实现。

安装

npm install --save-dev @babel/template

字符串用法

template使用带有字符串参数的函数进行调用时,可以提供占位符,这些占位符将在使用模板时被替换。

您可以使用两种不同的占位符:语法占位符(例如%%name%%)或标识符占位符(例如NAME)。@babel/template默认情况下支持这两种方法,但是不能混用。如果需要明确说明所使用的语法,则可以使用该syntacticPlaceholders选项。

请注意,语法占位符是在Babel 7.4.0中引入的。如果您不控制@babel/template版本(例如,从@babel/core@^7.0.0对等依赖项导入版本),则必须使用标识符占位符。另一方面,句法占位符有一些优点:它们可用于标识符可能是语法错误的地方(例如,代替函数体或在导出声明中使用),并且它们不与大写变量(例如,new URL()冲突

输入(语法占位符):

import template from "@babel/template"; import generate from "@babel/generator"; import * as t from "@babel/types"; const buildRequire = template(` var %%importName%% = require(%%source%%); `); const ast = buildRequire({ importName: t.identifier("myModule"), source: t.stringLiteral("my-module"), }); console.log(generate(ast).code);

输入(标识符占位符):

const buildRequire = template(` var IMPORT_NAME = require(SOURCE); `); const ast = buildRequire({ IMPORT_NAME: t.identifier("myModule"), SOURCE: t.stringLiteral("my-module"), });

const myModule = require("my-module");

.ast

如果没有使用占位符,并且您只想一种简单的方法将字符串解析为AST,则可以使用.ast模板版本。

const ast = template.ast(` var myModule = require("my-module"); `);

它将解析并直接返回AST。

模板文字用法

import template from "@babel/template"; import generate from "@babel/generator"; import * as t from "@babel/types"; const source = "my-module"; const fn = template` var IMPORT_NAME = require('${source}'); `; const ast = fn({ IMPORT_NAME: t.identifier("myModule"), }); console.log(generate(ast).code);

请注意,可以将占位符作为模板文字的一部分直接传递,以使内容尽可能地可读,也可以将它们传递到模板函数中。

.ast

如果没有使用占位符,并且您只想一种简单的方法将字符串解析为AST,则可以使用.ast模板版本。

const name = "my-module"; const mod = "myModule"; const ast = template.ast` var ${mod} = require("${name}"); `;

它将解析并直接返回AST。请注意,与前面提到的基于字符串的版本不同,由于这是模板文字,因此使用模板文字替换执行替换仍然有效。

AST结果

@babel/templateAPI公开了一些灵活的API,以使其尽可能容易地创建具有预期结构的AST。这些中的每一个还具有上述.ast属性。

template

template 根据解析的结果返回一个语句或语句数组。

template.smart

这与默认templateAPI 相同,根据解析结果返回单个节点或节点数组。

template.statement

template.statement("foo;")() 返回单个语句节点,如果结果不是单个语句,则抛出异常。

template.statements

template.statements("foo;foo;")() 返回语句节点的数组。

template.expression

template.expression("foo")() 返回表达式节点。

template.program

template.program("foo;")()返回Program模板节点。

API

template(code, [opts])

类型: string

选项

@babel/template接受Babel Parser的所有选项,并指定一些自己的默认值:

  • allowReturnOutsideFunctiontrue默认设置为
  • allowSuperOutsideMethodtrue默认设置为
  • sourceTypemodule默认设置为

句法占位符

类型:boolean 默认值:true如果使用%%foo%%-style占位符;false除此以外。

如果此选项为true,则可以%%foo%%在模板中标记占位符。如果为false,则占位符是由placeholderWhitelistplaceholderPattern选项确定的标识符

占位符

类型:Set<string> 默认值:undefined

该选项与 syntacticPlaceholders: true

一组自动接受的占位符名称。此列表中的项目不需要匹配给定的占位符模式。

占位符模式

类型:RegExp | false 默认值:/^[_$A-Z0-9]+$/

该选项与 syntacticPlaceholders: true

查找标识符和StringLiteral节点时应被视为占位符的搜索模式。“ false”将完全禁用占位符搜索,仅保留“ placeholderWhitelist”值来查找占位符。

reserveComments

类型:boolean 默认值:false

设置此选项可true保留code参数中的所有注释

返回值

默认情况下,@babel/template返回a function,该替代对象由替换的可选对象调用。有关示例,请参见用法部分。

使用时.ast,AST将直接返回。

@ babel /遍历

安装

$ npm install --save @babel/traverse

用法

我们可以将其与babel解析器一起使用来遍历和更新节点:

import * as parser from "@babel/parser"; import traverse from "@babel/traverse"; const code = `function square(n) { return n * n; }`; const ast = parser.parse(code); traverse(ast, { enter(path) { if (path.isIdentifier({ name: "n" })) { path.node.name = "x"; } } });

另外,我们可以在语法树中定位特定的节点类型

traverse(ast, { FunctionDeclaration: function(path) { path.node.id.name = "x"; } })

@ babel /类型

npm install --save-dev @babel/types

API

anyTypeAnnotation

t.anyTypeAnnotation()

arrayExpression

t.arrayExpression(elements)

另请参阅t.isArrayExpression(node, opts)t.assertArrayExpression(node, opts)

别名: Expression

  • elementsArray<null | Expression | SpreadElement>(默认:[]

argumentsPlaceholder

t.argumentPlaceholder()

另请参阅t.isArgumentPlaceholder(node, opts)t.assertArgumentPlaceholder(node, opts)

别名:无

arrayPattern

t.arrayPattern(elements)

另请参阅t.isArrayPattern(node, opts)t.assertArrayPattern(node, opts)

别名:PatternPatternLikeLVal

  • elements:(Array<PatternLike>必填)
  • decoratorsArray<Decorator>(默认:null
  • typeAnnotationTypeAnnotation | TSTypeAnnotation | Noop(默认:null

arrayTypeAnnotation

t.arrayTypeAnnotation(elementType)

另请参阅t.isArrayTypeAnnotation(node, opts)t.assertArrayTypeAnnotation(node, opts)

别名:FlowFlowType

  • elementType:(FlowType必填)

arrowFunctionExpression

t.arrowFunctionExpression(params, body, async)

另请参阅t.isArrowFunctionExpression(node, opts)t.assertArrowFunctionExpression(node, opts)

别名:ScopableFunctionBlockParentFunctionParentExpressionPureish

  • params:(Array<LVal>必填)
  • body:(BlockStatement | Expression必填)
  • asyncboolean(默认:false
  • expressionboolean(默认:null
  • generatorboolean(默认:false
  • returnTypeTypeAnnotation | TSTypeAnnotation | Noop(默认:null
  • typeParametersTypeParameterDeclaration | TSTypeParameterDeclaration | Noop(默认:null

assignmentExpression

t.assignmentExpression(operator, left, right)

另请参阅t.isAssignmentExpression(node, opts)t.assertAssignmentExpression(node, opts)

别名: Expression

  • operator:(string必填)
  • left:(LVal必填)
  • right:(Expression必填)

AssignmentPattern

t.assignmentPattern(left, right)

另请参阅t.isAssignmentPattern(node, opts)t.assertAssignmentPattern(node, opts)

别名:PatternPatternLikeLVal

  • left:(Identifier | ObjectPattern | ArrayPattern必填)
  • right:(Expression必填)
  • decoratorsArray<Decorator>(默认:null
  • typeAnnotationTypeAnnotation | TSTypeAnnotation | Noop(默认:null

awaitExpression

t.awaitExpression(argument)

另请参阅t.isAwaitExpression(node, opts)t.assertAwaitExpression(node, opts)

别名:ExpressionTerminatorless

  • argument:(Expression必填)

bigIntLiteral

         t.bigIntLiteral(value)

另请参阅t.isBigIntLiteral(node, opts)t.assertBigIntLiteral(node, opts)

别名:ExpressionPureishLiteralImmutable

  • value:(string必填)

binaryExpression

t.binaryExpression(operator, left, right)

另请参阅t.isBinaryExpression(node, opts)t.assertBinaryExpression(node, opts)

别名:BinaryExpression

  • operator:("+" | "-" | "/" | "%" | "*" | "**" | "&" | "|" | ">>" | ">>>" | "<<" | "^" | "==" | "===" | "!=" | "!==" | "in" | "instanceof" | ">" | "<" | ">=" | "<="必填)
  • left:(Expression必填)
  • right:(Expression必填)

bindExpression

t.bindExpression(object, callee)

另请参阅t.isBindExpression(node, opts)t.assertBindExpression(node, opts)

别名: Expression

  • object (需要)
  • callee (需要)
原文地址:https://www.cnblogs.com/zhouyideboke/p/12221452.html