babel 原理
- parse: 把原始代码 code 变成 AST
- traverse: 遍历 AST 进行修改
- generate: 把 AST 变成代码 code2
即 code --(parse)--> ast --(traverse)-> ast2 --(generate)-> code2
//var_to_let.ts
let code = 'var a = "let";var b = 2'
const ast = parse(code,{sourceType:'module'})
console.log(ast)
运行下面代码后,打开 Chrome 开发者工具,点击 Node 图标即可调试
node -r ts-node/register --inspect-brk var_to_let.ts
image.png
image.png image.png image.png
例:把代码中的 var 转换成 let
import {parse} from '@babel/core'
import traverse from '@babel/traverse';
import generate from '@babel/generator';
let code = 'var a = "let";var b = 2'
const ast = parse(code,{sourceType:'module'})
// 遍历AST
traverse(ast,{
// 每进入一个节点执行enter钩子函数
enter:item =>{
if(item.node.type === 'VariableDeclaration'){
if(item.node.kind === 'var'){
item.node.kind = 'let'
}
}
}
})
let result = generate(ast,{},code)
console.log(result.code);
let a = "let"; let b = 2;
例:把代码转换成 ES5
import * as babel from '@babel/core';
import {parse} from '@babel/core';
const code = `var a = 'a';let b = "b"; const c = 'c'`;
const ast = parse(code, {sourceType: 'module'});
const result = babel.transformFromAstSync(ast, code, {
presets: ['@babel/preset-env']
});
console.log(result.code);
例:把文件转换成 ES5
import * as babel from '@babel/core';
import {parse} from '@babel/core';
import * as fs from 'fs'
// TODO test.js 改为任意文件
const code = fs.readFileSync("./test.js").toString()
const ast = parse(code, {sourceType: 'module'});
const result = babel.transformFromAstSync(ast, code, {
presets: ['@babel/preset-env']
});
fs.writeFileSync('./test.es5.js',result.code)
网友评论