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)
:获取某个属性的path
set(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',
}
]
]
})