Babylon-AST初探-代码更新删除(Update Remove)
??通過(guò)前兩篇文章的介紹,大家已經(jīng)了解了Create和Retrieve,我們接著介紹Update和 Remove操作。Update操作通常配合Create來(lái)完成。我們這篇文章主要介紹幾個(gè)常用的NodePath`API:replace、insert、remove`。具體也可以看babel-handbook中的Manipulation章節(jié)。
replaceWith 使用新的節(jié)點(diǎn)進(jìn)行替換
將加法運(yùn)算替換成乘法
const code = `const c = a + b` const ast = babylon.parse(code)traverse(ast, {BinaryExpression(path) {// 注意這里要有判斷,否則會(huì)無(wú)限進(jìn)入`BinaryExpression`// https://stackoverflow.com/questions/37539432/babel-maximum-call-stack-size-exceeded-while-using-path-replacewithif (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
??轉(zhuǎn)換前后的AST展示如下圖:
??我們需要做的是,找到符合this.count的ThisExpression,然后把它替換為this.data
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;replaceWithSourceString 直接使用代碼替換
??上個(gè)例子中將this.count替換為this.data.count的部分,通過(guò)t.memberExpression可以構(gòu)造node。更簡(jiǎn)單的操作可以直接使用replaceWithSourceString,個(gè)人覺(jué)得這個(gè)API很好用。
path.get('object').replaceWithSourceString('this.data')插入操作
??插入是樹(shù)操作的一種常見(jiàn)操作。子節(jié)點(diǎn)是個(gè)Array,前、中、后各種位置都可以插入新節(jié)點(diǎn)。下面來(lái)介紹下pushContainer、unshiftContainer、insertBefore、insertAfter操作。
??這里以給obj對(duì)象新增一個(gè)屬性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') )pushContainer 父節(jié)點(diǎn)的操作
??父節(jié)點(diǎn)為子節(jié)點(diǎn)Array插入一個(gè)node
traverse(ast, {ObjectExpression(path) {path.pushContainer('properties', property)} })insertAfter 兄弟節(jié)點(diǎn)的操作
??insertAfter也可以完成上述操作,需要找到message屬性,然后在后面插入node就搞定啦
traverse(ast, {ObjectProperty(path) {if (t.isIdentifier(path.node.key, {name: 'message'})) {path.insertAfter(property)}} })??unshiftContainer和insertBefore與上面兩個(gè)相對(duì)應(yīng),這里不再舉例了,大家可以自己試一試。
??因?yàn)閜roperties是個(gè)數(shù)組,因此,我們可以直接使用數(shù)組操作
traverse(ast, {ObjectExpression(path) {// path.pushContainer('properties', property)path.node.properties.push(property)} })Remove 自我毀滅
??Remove方法極為簡(jiǎn)單,找到要?jiǎng)h除的NodePath,執(zhí)行Remove就結(jié)束了。如上述代碼,我們要?jiǎng)h除message屬性,代碼如下:
traverse(ast, {ObjectProperty(path) {if (t.isIdentifier(path.node.key, {name: 'message'})) {path.remove()}} })到目前為止,AST的CURD我們都介紹完了,下面一篇文章以vue轉(zhuǎn)小程序?yàn)槔?#xff0c;我們來(lái)實(shí)戰(zhàn)一波。
總結(jié)
以上是生活随笔為你收集整理的Babylon-AST初探-代码更新删除(Update Remove)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 初级英语02
- 下一篇: 使用IHttpHandler做权限控制[