Babel基础
相关工具文档
Babylon是Babel的解析器。最初是Acorn的一份fork,它非常快,易于使用,并且针对非标准特性(以及那些未来的标准特性)设计了一个基于插件的架构。
Babel Tranverse(遍历)模块维护了整棵树的状态,并且负责替换、移除和添加节点。
- babel-types-api文档
Babel Types(类型)模块是一个用于AST节点的Lodash式工具库。 它包含了构造、验证以及变换AST节点的方法。 其设计周到的工具方法有助于编写清晰简单的AST逻辑。
Babel Generator是Babel的代码生成器。它将AST输出为代码并包括源码映射(sourcemaps)。
Babel Template模块是一个很小但却非常有用的模块。它能让你编写带有占位符的字符串形式的代码,你可以用此来替代大量的手工构建的AST。
相关Api
Visitor
visitor是一个对象,对象中定义了用于获取AST中具体节点的方法,例如ImportDeclaration、CallExpression等等
javascript
const addCodePlugin = ({types}) => {
return {
visitor: {
ImportDeclaration(path) {
const { node } = path;
// ......
},
ObjectMethod(path, state) {
const {node} = path;
if (!types.isIdentifier(node.key)) return;
console.log("<<<<<<<<<<<<<<<<<<<<<<<<<<<<", node.key.name, state.opts, ">>>>>>>>>>>>>>>>");
},
}
};
};
Path
visitor中对象定义的方法的第一个参数,path是一个对象,它表示两个节点之间的连接path的属性和方法node:当前AST节点parent:父AST节点parentPath:父AST节点的路径scope:作用域get(key):获取某个属性的pathset(key, node):设置某个属性is类型(opts): 判断当前节点是否是某个类型find(callback): 从当前节点一直向上找到根节点(包括自己)findParent(callback):从当前节点一直向上找到根节点(不包括自己)insertBefore(nodes):在之前插入节点insertAfter(nodes):在之后插入节点replaceWith(replacement):用某个节点替换当前节点replaceWithMultiple(nodes): 用多个节点替换当前节点replaceWithSourceString(replacement):把源代码转成AST节点再替换当前节点remove():删除当前节点traverse(visitor, state): 遍历当前节点的子节点,第1个参数是节点,第2个参数是用来传递数据的状态skip():跳过当前节点子节点的遍历stop():结束所有的遍历
Scope(作用域)
scope的属性和方法scope.bindings:当前作用域内声明所有变量scope.path:生成作用域的节点对应的路径scope.references:所有的变量引用的路径getAllBindings():获取从当前作用域一直到根作用域的集合getBinding(name):从当前作用域到根使用域查找变量getOwnBinding(name):在当前作用域查找变量parentHasBinding(name, noGlobals):从当前父作用域到根使用域查找变量removeBinding(name):删除变量hasBinding(name, noGlobals):判断是否包含变量moveBindingTo(name, scope):把当前作用域的变量移动到其它作用域中generateUid(name):生成作用域中的唯一变量名,如果变量名被占用就在前面加下划线
插件选项
插件编写和调用几种方法
js
const code = `
function foo(a, b) {
console.log(a, b);
}
`;
第一种
使用插件的时候,使用调用插件函数的方法,传入参数,此时函数接受的
opts就是函数传的参数
js
const addCodePlugin = (opts) => {
console.log(opts) // { city: 'shanghai' }
return {
visitor: {
FunctionDeclaration(path, state) {
console.log(state.opts, 'state.opts'); // { like: 'pingPang' }
}
}
}
}
const res = babel.transform(code, {
plugins: [
[
addCodePlugin({city: 'shanghai'}),
{
like: 'pingPang',
}
]
]
})
第二种
使用插件的时候,不使用调用插件函数的方法,此时函数中接受的
opts就是默认参数,其中的types最常用,它其实就是@babel/types这个包的所有方法集合,传入的参数就可以通过函数第二个参数state.opts来获取
js
const addCodePlugin = ({types}) => {
return {
visitor: {
FunctionDeclaration(path, state) {
console.log(state.opts, 'state.opts'); // { like: 'pingPang' }
}
}
}
}
const res = babel.transform(code, {
plugins: [
[
addCodePlugin,
{
like: 'pingPang',
}
]
]
})