[AST Tools] Babel template: replace JQuery

For example we have following code:

$(el).hide() // el.style.display = 'none'
$(el).forEach(() => {})
foo.hide()

We want

$(el).hide()

replace with:

el.style.display = 'none'

 

Plugin:

export default function (babel) {
  const { types: t, template } = babel;
  
  return {
    name: "ast-transform", // not required
    visitor: {
      CallExpression(path) {

          const isJqueryCallExpression = looksLike(path, {
            node: {
                callee: {
                    name: '$'
                }
            },
            parent: {
                type: "MemberExpression",
                property: {
                    name: 'hide'
                }
            }
        });
        
        if (!isJqueryCallExpression) {
            return 
        }
        const overallPath = path.parentPath.parentPath;
        const templateString = `EL.style.display = 'none';`
        const assignmentBuilder = template(templateString)
        const assignment = assignmentBuilder({
            EL: t.identifier(path.node.arguments[0].name)
        })
        overallPath.replaceWith(assignment)
      }
    }
  };
}


function looksLike(a, b) {
  return (
    a &&
    b &&
    Object.keys(b).every(bKey => {
      const bVal = b[bKey]
      const aVal = a[bKey]
      if (typeof bVal === 'function') {
        return bVal(aVal)
      }
      return isPrimitive(bVal) ? bVal === aVal : looksLike(aVal, bVal)
    })
  )
}

function isPrimitive(val) {
  return val == null || /^[sbn]/.test(typeof val)
}

 

posted @ 2020-03-05 17:58  Zhentiw  阅读(129)  评论(0编辑  收藏  举报