抽象语法树 ast

2019-10-04  本文已影响0人  我叫Aliya但是被占用了
  1. 源代码转换成树 插件用 esprima

    https://astexplorer.net/ 在线生成代码树

  2. 深度优先遍历 estraverse

  3. 改变数

  4. 生成树 escodegen

let esprima = require("esprima");
let estraverse = require("estraverse");
let escodegen = require( "escodegen");

let code = 'function a () {}'

let ast = esprima.parseScript(code) // 解析脚本,生成树
estraverse.traverse(ast, {      // 遍历树
    enter (node) { 
        console.log('enter: ',node.type)
        if (node.type == "Identifier") node.name = 'hahaha' // 修改树
    },
    leave (node) { 
        console.log('leave: ',node.type)
    }
})

let r = escodegen.generate(ast) // 生成新脚本
console.log(typeof r, r)

用于代码混淆压缩、语法检查、格式检查、错误提示、自动补全等

利用babel,es6 剪头函数 转es5

// es6 剪头函数 转es5
let babel = require('@babel/core')
let code = 'let fn = (a,b) => a+b'

let r = babel.transform(code, {
    plugins: [
        '@babel/plugin-transform-arrow-functions'
    ]
    // presets: [
    //     '@babel/preset-env'
    // ]
})
console.log(r.code)

借助 https://astexplorer.net/ 自己实现es6剪头函数转es5

// es6 剪头函数 转es5
let babel = require('@babel/core')
let t = require('@babel/types')
let code = 'let fn = (a,b) => a+b'
let arrowFunctions = {
    visitor: {      // 访问者模式
        ArrowFunctionExpression(path) {
            let node = path.node
            let body = node.body
            if (t.isBinaryExpression(body)) { // 是二进制流,不是函数体
                body = t.blockStatement([t.returnStatement(body)])
            }
            // 生成一个新 es5方法 结点
            let newnode = t.functionExpression(null, node.params, body)
            path.replaceWith(newnode)
        }
    }
}

let r = babel.transform(code, {
    plugins: [
        arrowFunctions
        // '@babel/plugin-transform-arrow-functions'
    ]
    // presets: [
    //     '@babel/preset-env'
    // ]
})
console.log(r.code)
上一篇 下一篇

猜你喜欢

热点阅读