编译步骤
Babel 编译文件的主要处理步骤依次是:解析(parse)、转换(transform)、生成(generate)。
- 解析:解析步骤主要是接受源代码并输出抽象语法树(AST)。此步骤主要由@babel/parser(原 Babylon)负责解析和理解 js 代码,输出对应的 AST。
- 转换:转换步骤主要是接受 AST,并对其进行遍历,在此过程中会进行分析和修改 AST,这也是 Babel 插件主要工作的地方。此步骤主要用到@babel/traverse 和@babel/types 两个包。
- 生成:生成步骤主要是将(经过一系列转换之后的)AST 再转换为正常的字符串代码。此步骤主要由@babel/generator 深度优先遍历整个 AST,然后构建可以表示转换后代码的字符串。
注:AST 其实是一个每个节点包含特定属性的对象树
实现 babel 的编译过程
- 使用
@babel/parser
把代码格式化为 AST
树
- 使用
@babel/traverse
和 @babel/types
实现 AST
树的遍历及对树的特定节点的操作
- 使用
@babel/generator
生成目标代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| const parser = require('@babel/parser') const traverse = require('@babel/traverse').default const type = require('@babel/types') const generate = require('@babel/generator').default
const code = ` function test(n){ return n + 1 } ` const ast = parser.parse(code, { sourceType: 'module' })
traverse(ast, { enter(path) { console.log('enter', path.node.name) if (type.isIdentifier(path.node, { name: 'n' })) { path.replaceWith(type.identifier('x')) } }, exit(path) { console.log('exit', path.node.name) }, })
const target = generate(ast)
console.log(target.code)
|
参考