經過前兩篇文章的介紹,你們已經瞭解了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
轉小程序
爲例,咱們來實戰一波。