经过前两篇文章的介绍,你们已经了解了Create
和Retrieve
,咱们接着介绍Update
和 Remove
操做。Update
操做一般配合Create
来完成。咱们这篇文章主要介绍几个经常使用的NodePath``API
:replace
、insert
、remove
。具体也能够看babel-handbook中的Manipulation章节。vue
const code = `const c = a + b`
const ast = babylon.parse(code)
traverse(ast, {
BinaryExpression(path) {
// 注意这里要有判断,不然会无限进入`BinaryExpression`
// https://stackoverflow.com/questions/37539432/babel-maximum-call-stack-size-exceeded-while-using-path-replacewith
if (path.node.operator === '+') {
path.replaceWith(t.binaryExpression('*', path.node.left, path.node.right))
}
}
})
console.log(generate(ast, {}, code).code) // const c = a * b;
复制代码
this.count
替换为this.data.count
转换先后的AST
展现以下图:node
咱们须要作的是,找到符合this.count
的ThisExpression
,而后把它替换为this.data
git
const code = `this.count`
const ast = babylon.parse(code)
traverse(ast, {
MemberExpression(path) {
if (
t.isThisExpression(path.node.object) &&
t.isIdentifier(path.node.property, {
name: 'count'
})
) {
path
.get('object') // 获取`ThisExpresssion`
.replaceWith(
t.memberExpression(t.thisExpression(), t.identifier('data'))
)
}
}
})
console.log(generate(ast, {}, code).code) // this.data.count;
复制代码
上个例子中将this.count
替换为this.data.count
的部分,经过t.memberExpression
能够构造node
。更简单的操做能够直接使用replaceWithSourceString
,我的以为这个API
很好用。github
path.get('object').replaceWithSourceString('this.data')
复制代码
插入是树操做的一种常见操做。子节点是个Array
,前、中、后各类位置均可以插入新节点。下面来介绍下pushContainer
、unshiftContainer
、insertBefore
、insertAfter
操做。小程序
这里以给obj
对象新增一个属性myprop: 'hello my property'
为例:数组
const code = `
const obj = {
count: 0,
message: 'hello world'
}
`
const ast = babylon.parse(code)
const property = t.objectProperty(
t.identifier('myprop'),
t.stringLiteral('hello my property')
)
复制代码
父节点为子节点Array
插入一个node
bash
traverse(ast, {
ObjectExpression(path) {
path.pushContainer('properties', property)
}
})
复制代码
insertAfter
也能够完成上述操做,须要找到message
属性,而后在后面插入node
就搞定啦babel
traverse(ast, {
ObjectProperty(path) {
if (
t.isIdentifier(path.node.key, {
name: 'message'
})
) {
path.insertAfter(property)
}
}
})
复制代码
unshiftContainer
和insertBefore
与上面两个相对应,这里再也不举例了,你们能够本身试一试。ide
由于properties
是个数组,所以,咱们能够直接使用数组操做ui
traverse(ast, {
ObjectExpression(path) {
// path.pushContainer('properties', property)
path.node.properties.push(property)
}
})
复制代码
Remove
方法极为简单,找到要删除的NodePath
,执行Remove
就结束了。如上述代码,咱们要删除message
属性,代码以下:
traverse(ast, {
ObjectProperty(path) {
if (
t.isIdentifier(path.node.key, {
name: 'message'
})
) {
path.remove()
}
}
})
复制代码
到目前为止,AST的CURD
咱们都介绍完了,下面一篇文章以vue
转小程序
为例,咱们来实战一波。