Babylon-AST初探-代码更新&删除(Update & Remove)

  经过前两篇文章的介绍,你们已经了解了CreateRetrieve,咱们接着介绍UpdateRemove操做。Update操做一般配合Create来完成。咱们这篇文章主要介绍几个经常使用的NodePath``APIreplaceinsertremove。具体也能够看babel-handbook中的Manipulation章节vue

replaceWith 使用新的节点进行替换

将加法运算替换成乘法

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.countThisExpression,而后把它替换为this.datagit

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 直接使用代码替换

  上个例子中将this.count替换为this.data.count的部分,经过t.memberExpression能够构造node。更简单的操做能够直接使用replaceWithSourceString,我的以为这个API很好用。github

path.get('object').replaceWithSourceString('this.data')
复制代码

插入操做

  插入是树操做的一种常见操做。子节点是个Array,前、中、后各类位置均可以插入新节点。下面来介绍下pushContainerunshiftContainerinsertBeforeinsertAfter操做。小程序

  这里以给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')
)
复制代码

pushContainer 父节点的操做

  父节点为子节点Array插入一个nodebash

traverse(ast, {
  ObjectExpression(path) {
    path.pushContainer('properties', property)
  }
})
复制代码

insertAfter 兄弟节点的操做

  insertAfter也能够完成上述操做,须要找到message属性,而后在后面插入node就搞定啦babel

traverse(ast, {
  ObjectProperty(path) {
    if (
      t.isIdentifier(path.node.key, {
        name: 'message'
      })
    ) {
      path.insertAfter(property)
    }
  }
})
复制代码

  unshiftContainerinsertBefore与上面两个相对应,这里再也不举例了,你们能够本身试一试。ide

  由于properties是个数组,所以,咱们能够直接使用数组操做ui

traverse(ast, {
  ObjectExpression(path) {
    // path.pushContainer('properties', property)
    path.node.properties.push(property)
  }
})
复制代码

Remove 自我毁灭

  Remove方法极为简单,找到要删除的NodePath,执行Remove就结束了。如上述代码,咱们要删除message属性,代码以下:

traverse(ast, {
  ObjectProperty(path) {
    if (
      t.isIdentifier(path.node.key, {
        name: 'message'
      })
    ) {
      path.remove()
    }
  }
})
复制代码

到目前为止,AST的CURD咱们都介绍完了,下面一篇文章以vue小程序为例,咱们来实战一波。

相关文章
相关标签/搜索