← 返回目录

第 25 卷

第 25 / 26 卷日期:

25] 26}

27] 28}

(2)步骤2:转换(Transform)→ 修改 AST

核心任务:遍历并修改 AST,将 ES6+ 相关的节点转换为 ES5 等价节点(如将箭头函数节点转为普通函数节点)。这是 Babel 编译的核心步骤,所有转译逻辑(插件/预设)都在此阶段作用于 AST。

实现工具: @babel/traverse(遍历 AST)、 @babel/types(创建/修改 AST 节点)。

具体流程:

1.@babel/traverse 遍历 AST 的所有节点(深度优先遍历)。

  1. 插件/预设注册的回调函数被触发(如遇到 ArrowFunctionExpression 节点时执行转译逻辑)。

3.@babel/types 创建新的 ES5 节点(如 FunctionExpression),替换原有的 ES6+ 节点(如 ArrowFunctionExpression)。

示例:将上述箭头函数节点转换为普通函数节点后的 AST 片段:

Code block

1"init": {

2"type": "FunctionExpression", //普通函数表达式(替换箭头函数)
3"id": null, //匿名函数
4"params": [{"type": "Identifier", "name": "a"}, {"type": "Identifier",

"name": "b"}], 5"body": {

6"type": "BlockStatement", //函数体块语句
7"body": [
8{
9"type": "ReturnStatement", // return语句
10"argument": {
11"type": "BinaryExpression",
12"left": {"type": "Identifier", "name": "a"},
13"operator": "+",
14"right": {"type": "Identifier", "name": "b"}
15}
16}
17]
18}

实现工具: @babel/generator。

具体流程: @babel/generator 遍历转换后的 AST,根据节点类型(如 FunctionExpression、 ReturnStatement)生成对应的 ES5 代码字符串,最终输出格式化后的目标代码。

示例:从上述修改后的 AST 生成的 ES5 代码:

Code block

1var add = function (a, b) { 2return a + b;

3};

  1. AST 的核心作用总结

• 结构化代码表示:将非结构化的代码字符串转换为结构化的树形数据,让机器能够理解代码的语法

结构和逻辑关系。

• 转译的核心载体:Babel 的转译逻辑(插件/预设)不直接操作代码字符串,而是通过修改 AST 节

点实现语法转换,AST 是转译的“中间桥梁”。

• 代码分析与优化:除了转译,AST 还支持代码分析(如检测未使用的变量)、代码优化(如删除冗

余代码)、代码重构等操作(如 ESLint、Prettier 也依赖 AST)。

• 多语法支持:AST 可统一表示不同语法(如 ES6+、JSX、TypeScript),让 Babel 能够通过不同

的解析插件处理多种语法,最终生成统一的目标代码。

三十一、Babel插件是如何工作的?请描述编写自定义Babel插件的基本步骤

Babel 插件的核心工作原理是“在 Babel 编译的转换阶段,通过遍历 AST(抽象语法树),修改特定节点以实现代码转译/优化”。插件本质是一个返回对象的函数,该对象通过注册 AST 节点的访问器

(visitor),在遍历到目标节点时执行自定义逻辑(如修改节点、添加节点、删除节点)。

一、Babel 插件的工作原理

Babel 插件的工作流程紧密依赖 Babel 的编译流程(解析→转换→生成),核心聚焦“转换阶段”:

  1. 插件加载:Babel 启动时,会加载配置文件中指定的插件,执行插件函数并传入配置参数(如

preset 中的选项),获取插件返回的访问器对象。

  1. AST 遍历:Babel 通过 @babel/traverse 遍历解析生成的 AST,遍历过程中会触发对应节点

类型的访问器方法(如遍历到 ArrowFunctionExpression 节点时,触发插件中注册的 ArrowFunctionExpression 访问器)。

关键工具库:

  • @babel/traverse:用于遍历 AST 节点。
  • @babel/types(简称 t):用于创建、判断、修改 AST 节点(核心工具)。
  • @babel/core:提供插件所需的核心 API(如 types、template 等)。

二、编写自定义 Babel 插件的基本步骤

以“将 console.log 语句替换为自定义日志函数 log.info”的插件为例,说明编写步骤:

  1. 步骤1:明确插件需求与 AST 节点类型

需求:将代码中所有 console.log(xxx) 替换为 log.info(xxx)。

分析 AST 节点:通过 AST Explorer(在线 AST 可视化工具)分析 console.log(123) 的 AST 结构,关键节点:

  • CallExpression:函数调用节点(整个 console.log(123))。

• MemberExpression:成员表达式节点( console.log),包含 object(console)

和 property(log)。

  • Identifier:标识符节点(console、log)。
  • NumericLiteral:数值字面量节点(123)。
  1. 步骤2:初始化插件项目

创建插件目录并初始化 npm 项目,安装依赖:

Code block

1mkdir babel-plugin-replace-console-log && cd babel-plugin-replace-console-log
2npm init -y
3npm install --save-dev @babel/core @babel/types @babel/traverse
  1. 步骤3:编写插件核心逻辑

创建插件入口文件 index.js,插件是一个接收 api 和 options 参数的函数,返回包含 visitor 的对象:

Code block

1// index.js

全站分卷索引 · 26 卷
  1. 1第 1 卷
  2. 2第 2 卷
  3. 3第 3 卷
  4. 4第 4 卷
  5. 5第 5 卷
  6. 6第 6 卷
  7. 7第 7 卷
  8. 8第 8 卷
  9. 9第 9 卷
  10. 10第 10 卷
  11. 11第 11 卷
  12. 12第 12 卷
  13. 13第 13 卷
  14. 14第 14 卷
  15. 15第 15 卷
  16. 16第 16 卷
  17. 17第 17 卷
  18. 18第 18 卷
  19. 19第 19 卷
  20. 20第 20 卷
  21. 21第 21 卷
  22. 22第 22 卷
  23. 23第 23 卷
  24. 24第 24 卷
  25. 25第 25 卷
  26. 26第 26 卷