Skip to main content

@babel/generator

将 Babel AST 转换为代码。

安装​

🌐 Install

npm install --save-dev @babel/generator

用法​

🌐 Usage

JavaScript
import { parse } from "@babel/parser";
import { generate } from "@babel/generator";

const code = "class Example {}";
const ast = parse(code);

const output = generate(
ast,
{
/* options */
},
code
);
info

像空格或换行符这样的符号不会在 AST 中保留。当 Babel 从 AST 打印代码时,输出格式不一定有保证。

解析器插件支持​

🌐 Parser plugins support

Babel generator supports all the listed Babel parser plugins except estree. Note that parser plugins do not transform the code. For example, if you pass JSX <div></div> to babel generator, the result will still contain the div JSX element.

JavaScript
import { parse } from "@babel/parser";
import { generate } from "@babel/generator";

const code = "const Example = () => <div>example</div>";
const ast = parse(code, { plugins: ["jsx" ] });

const output = generate(
ast,
).code;

// true
output.includes("<div>");

应用接口​

🌐 API

Babel 生成器正好包含一个函数 generate。它可以用不同的方式导入。

🌐 Babel generator contains exactly one function generate. It can be imported in different ways.

JavaScript
const generate = require("@babel/generator");
const { generate } = require("@babel/generator");
import { generate } from "@babel/generator";

选项​

🌐 Options

历史
版本更改
v8.0.0移除了 importAttributesKeyword
v7.26.0添加了 experimental_preserveFormat
v7.22.0添加了 importAttributesKeyword
v7.21.0添加了 inputSourceMap

格式化输出的选项:

🌐 Options for formatting output:

名称类型默认值描述
auxiliaryCommentAfter字符串可选的字符串,用于在输出文件末尾作为块注释添加
auxiliaryCommentBefore字符串可选的字符串,用于在输出文件开头作为块注释添加
评论布尔值true输出中是否应包含评论
紧凑布尔值或 'auto'opts.minified设置为 true 以避免为格式化添加空格
简洁布尔值false设置为 true 可以减少空白(但没有 opts.compact 减少得多)
decoratorsBeforeExport布尔值设置为 true 以在输出中将装饰器打印在 export 之前。
文件名字符串用于警告信息
importAttributesKeyword(⚠️ 在 Babel 8 中已移除)"with"、"assert" 或 "with-legacy"要使用的 import 属性/断言语法。"with" 对应 import "..." with { type: "json" },"assert" 对应 import "..." assert { type: "json" },"with-legacy" 对应 import "..." with type: "json"。如果未指定,@babel/generator 将根据 AST 结构尝试匹配输入代码中的风格。
jsescOption对象使用 jsesc 处理字面量。jsesc 仅在存在 jsescOption.numbers(在 v7.9.0 中添加)时应用于数字。你可以通过 传递选项 来自定义 jsesc。
jsonCompatibleStrings布尔值false设置为 true 可运行 jsesc 并使用 "json": true 来打印 "\u00A9" 与 "©";
压缩布尔值false输出是否应压缩
retainFunctionParens布尔值false保留函数表达式周围的括号(可用于改变引擎解析行为)
retainLines布尔值false尝试在输出代码中使用与源代码相同的行号(有助于保留堆栈跟踪)
shouldPrintComment函数opts.comments一个接收评论(字符串形式)的函数,如果评论应该包含在输出中则返回 true。默认情况下,如果 opts.comments 是 true,或者如果 opts.minified 是 false 且评论包含 @preserve 或 @license,评论会被包含
recordAndTupleSyntaxType'hash' 或 'bar''hash'用于 recordAndTuple 标记。
topicToken'%' 或 '#'要与 Hack-pipe topic references 一起使用的 token。当存在任何 TopicReference 节点时,这是必需的。

源映射选项:

🌐 Options for source maps:

名称类型默认值描述
sourceMaps布尔值false启用生成源映射
inputSourceMap字符串或对象输入的源映射
sourceRoot字符串源映射中所有相对 URL 的根目录
sourceFileName字符串源代码的文件名(即 code 参数中的代码)。只有当 code 是字符串时才会使用。

实验选项:

🌐 Experimental options:

warning

实验性选项的行为在小版本更新中可能会有重大变化。

名称类型默认值描述实验原因
experimental_preserveFormat布尔值false设置为 true 时,生成器会尝试保留输入和输出代码中都存在的所有节点和标记的位置。要使用此选项,目前你需要启用 retainLines: true 生成器选项,以及 tokens: true 和 createParenthesizedExpressions: true 解析器选项。一旦该选项支持一种不需要保留行号,只保留标记相对位置的模式,它将从实验阶段转为稳定版。

结果​

🌐 Result

generate API 在启用 sourceMaps 选项时会返回一个包含源代码和源映射信息的对象。它的字段有:

🌐 The generate API returns an object containing the source code and the source map information when the sourceMaps option is enabled. Its fields are:

  • code: string - 从提供的 AST 输出的源代码
  • map: EncodedSourceMap | null - 输出源地图是编码形式。它是惰性计算的
  • decodedMap: DecodedSourceMap | undefined - 输出源地图是解码形式。它是惰性求值的
  • rawMappings: Mapping[] - 一个高级的映射对象,用于每个已记录的片段,以生成源映射。它是惰性求值的

来自多个来源的 AST​

🌐 AST from Multiple Sources

在大多数情况下,Babel 会将输入文件 1:1 转换为输出文件。不过,你可能会处理由多个来源构建的 AST —— JS 文件、模板等等。如果是这种情况,并且你希望 sourcemaps 能正确反映来源,你需要将一个对象作为 code 参数传给 generate。对象的键应该是源文件名,值应该是源内容。

🌐 In most cases, Babel does a 1:1 transformation of input-file to output-file. However, you may be dealing with AST constructed from multiple sources - JS files, templates, etc. If this is the case, and you want the sourcemaps to reflect the correct sources, you'll need to pass an object to generate as the code parameter. Keys should be the source filenames, and values should be the source content.

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

🌐 Here's an example of what that might look like:

JavaScript
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.