目的
使用 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])
另一个例子处理 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
@babel/types
@babel/template
@babel/code-frame
@babel/generator
@babel/core
总结
这一节我们了解了编译过程中各阶段的 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 , 接下来就可以开启实战部分,试试就试试