babel原理
Babel 的三个主要处理步骤分别是:解析(parse),转换(transform),生成(generate) babel 插件就是在转换过程中起作用的,即将解析完成的语法树对象按照自己的目的进行处理,然后再进行代码生成步骤。
如上图所示,插件起作用的步骤则是上图的transform阶段
插件实现步骤
- 将你要改变的代码生成ast
- 目标代码生成ast
- 观察以上两种ast的区别,然后进行转化(修改、增加、删除操作)
实践代码
下边已实现console代码的移除为例
- 观察代码生成的ast,转化网址astexplorer.net/
2. 插件index.js
module.exports = ({types: t})=>{
return {
visitor:{
Identifier(path){
console.log('path',path.node.name)
const parentIsIf = t.isIfStatement(path.parentPath)
const isDebug = path.node.name ==="DEBUG"
if(parentIsIf&&isDebug){
const stringNode = t.stringLiteral('DEBUG');
path.replaceWith(stringNode)
}
},
StringLiteral(path){
const parentIsIf = t.isIfStatement(path.parentPath)
const isDebug = path.node.value ==="DEBUG"
if(parentIsIf&&isDebug){
path.parentPath.remove()
}
}
}
// 如果是仅移除代码中的console可以用这段代码
// visitor:{
// Identifier(path){
// if (path.node.name === 'console') {
// path.findParent(p => p.isCallExpression()).remove();;
// }
// }
// }
测试方式
- 全局配置 .babelIrc
{
"presets": [
[
"@babel/env",
{
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
},
"corejs": { "version": 3 },
"useBuiltIns": false
}
]
],
"plugins": ["./index.js"]
// 如果只是在生产环境下移除的话还可以这样写
//"env": {
// "production": {
// "plugins": ["./index.js"]
// }
//}
}
- test页面测试
const {transformSync} =require('@babel/core')
const code = `
function add(num1,num2){
return num1+num2
}
if(DEBUG){
const sum = add(5,6)
console.log('sum',sum)
}
`
const babelConfig= {
plugins:['./index.js']
}
const output=transformSync(code,babelConfig)
console.log('output.code',output.code)