經過前兩篇文章的介紹,你們已經瞭解了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
babel
traverse(ast, { ObjectExpression(path) { path.pushContainer('properties', property) } })
insertAfter
也能夠完成上述操做,須要找到message
屬性,而後在後面插入node
就搞定啦ide
traverse(ast, { ObjectProperty(path) { if ( t.isIdentifier(path.node.key, { name: 'message' }) ) { path.insertAfter(property) } } })
unshiftContainer
和insertBefore
與上面兩個相對應,這裏再也不舉例了,你們能夠本身試一試。ui
由於properties
是個數組,所以,咱們能夠直接使用數組操做this
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
轉小程序
爲例,咱們來實戰一波。