4、 Babel 的 API

151 阅读2分钟

目的

使用 API 才能操作 AST

babel 的 api 有哪些

babel 的编译流程分为三步:parse、transform、generate,每一步都暴露了一些 api 出来(类似于vue/react 生命周期,或者 js 一些监听)。

  • parse 阶段有@babel/parser,功能是把源码转成 AST
  • transform 阶段有 @babel/traverse,可以遍历 AST,并调用 visitor 函数修改 AST,修改 AST 自然涉及到 AST 的判断、创建、修改等,这时候就需要 @babel/types 了,当需要批量创建 AST 的时候可以使用 @babel/template 来简化 AST 创建逻辑。
  • generate 阶段会把 AST 打印为目标代码字符串,同时生成 sourcemap,需要 @babel/generator 包
  • 中途遇到错误想打印代码位置的时候,使用 @babel/code-frame 包
  • babel 的整体功能通过 @babel/core 提供,基于上面的包完成 babel 整体的编译流程,并应用 plugin 和 preset。

学习 @babel/parser@babel/traverse@babel/generator@babel/types@babel/template 这五个包的 api 的使用。

@babel/parser

将 JavaScript 源代码解析为抽象语法树(AST, Abstract Syntax Tree)。AST 是代码的结构化表示,Babel 在转换代码时依赖这个 AST 作为中间形式。

它提供了有两个 api:parse 和 parseExpression。两者都是把源码转成 AST,不过 parse 返回的 AST 根节点是 File(整个 AST),parseExpression 返回的 AST 根节点是是 Expression(表达式的 AST),粒度不同。

babelParser.parse(code, [options])
babelParser.parseExpression(code, [options])

image.png

另一个例子处理 es6

const code = `const result = obj?.value ?? 'default';`;

const ast = parser.parse(code, {
  sourceType: 'module', // 表示这是一个 ES Module
  plugins: ['optionalChaining', 'nullishCoalescingOperator'], // 支持的新特性
});

console.log(JSON.stringify(ast, null, 2));

@babel/traverse

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

@babel/types

image.png

@babel/template

image.png

image.png

@babel/code-frame

image.png

@babel/generator

image.png

@babel/core

image.png

总结

这一节我们了解了编译过程中各阶段的 api:

  • @babel/parser 对源码进行 parse,可以通过 plugins、sourceType 等来指定 parse 语法
  • @babel/traverse 通过 visitor 函数对遍历到的 ast 进行处理,分为 enter 和 exit 两个阶段,具体操作 AST 使用 path 的 api,还可以通过 state 来在遍历过程中传递一些数据
  • @babel/types 用于创建、判断 AST 节点,提供了 xxx、isXxx、assertXxx 的 api
  • @babel/template 用于批量创建节点
  • @babel/code-frame 可以创建友好的报错信息
  • @babel/generator 打印 AST 成目标代码字符串,支持 comments、minified、sourceMaps 等选项。
  • @babel/core 基于上面的包来完成 babel 的编译流程,可以从源码字符串、源码文件、AST 开始。

nice , 接下来就可以开启实战部分,试试就试试