详解使用抽象语法树AST实现一个AOP切面逻辑

 更新时间:2023年04月06日 17:03:19   作者:头疼脑胀的代码搬运工  
这篇文章主要为大家介绍了使用抽象语法树AST实现一个AOP切面逻辑的简单方法,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

开篇

AST 功能很灵活,可以通过改变一些自定义结构便可以输入自定义的功能,下面简单的展示下如何利用抽象语法树AST实现一个AOP切面逻辑

一、实现目的

js 文件下的全部方法添加一个开始事件和一个结束事件并传入方法名,以便监听某个方法的调用。

1、work.js

function eat(){
    let food = "apple"
    let time = '2小时'
    return '吃' + food + '用时' + time
}
function work(){
}
console.log(eat())

控制台打印

可以看到,输入了执行 eat 方法的开始事件及结束事件。其实,这个过程就是 work.js 转成语法树后,对方法节点进行了处理,添加了两个切面方法:startend 事件。

2、aop.js

这个文件用来声明 startend 事件。

function start(funcName){
    console.log('开始执行:' + funcName + '方法')
}
function end(funcName){
    console.log('执行结束:' + funcName + '方法')
}

二、利用语法树添加切面事件

//文件操作工具
const fs = require('fs');
//JS代码转语法树工具
const parser = require('./babel-core/node_modules/babylon');
//语法树遍历工具
const traverse = require('./babel-core/node_modules/babel-traverse');
//语法树转JS代码工具
const generator = require('./babel-core/node_modules/babel-generator');
//声明语法树类型工具
const t = require('./babel-core/node_modules/babel-types');
//获取aop代码
let aop = fs.readFileSync('./aop.js','utf-8')
//获取需要添加切面的代码
let content = fs.readFileSync('./work.js','utf-8')
//将需要添加切面的代码转换为语法树
let ast = parser.parse(content,{
    sourceType:'script'
})
//遍历指定语法树时操作项(这里遍历的指定节点是FunctionDeclaration方法)
const visitor = {
    FunctionDeclaration:({ node }) => {
        //获取每个方法体里面的节点
        let funcBody = node.body.body
        //创建一个名为start,参数为当前方法名的执行节点,后面的参数为创建一个名为start方法的参数
        let start = t.callExpression(t.identifier('start'), [t.identifier(`"${node.id.name}"`)])
        //添加到方法的最前面
        funcBody.unshift(start)
        //判断最后一个节点是不是return,方式结束事件调用节点在最后无法调用。
        let lastNode = funcBody.slice(-1)
        //创建一个名为end,参数为当前方法名的执行节点,后面的参数为end方法的参数
        let end = t.callExpression(t.identifier('end'), [t.identifier(`"${node.id.name}"`)])
        //设定end节点添加的位置
        let insertEndEventPosition = (funcBody.length)
        if(lastNode[0].type == 'ReturnStatement'){
            //放在return节点的前面
            insertEndEventPosition -= 1
        }
        //添加end节点
        funcBody.splice(insertEndEventPosition,0,end)
    }
}
//开始遍历操作语法树
traverse.default(ast,visitor)
//将处理完的语法树再次转换为JS代码
let codeResult = generator.default(ast)
//这里需要添加aop里面的两个切面事件到最终的JS代码里。
let outFileCode = aop + '\n\n' + codeResult.code
// 写入文件操作
fs.mkdir('cache',(err)=>{
    if(!err){
        fs.writeFile('cache/main.js',outFileCode,(err)=>{
            if(!err){
                console.log('文件创建完成')
            }
        })
    }
})

上面的代码执行完后,看下 main.js 生成的代码内容。

function start(funcName){
    console.log('开始执行:' + funcName + '方法')
}
function end(funcName){
    console.log('执行结束:' + funcName + '方法')
}
function eat() {
    start("eat")
    let food = "apple";
    let time = '2小时';
    end("eat")
    return '吃' + food + '用时' + time;
}
function work() {
    start("work")
    end("work")
}
console.log(eat());

相比较之前的 work.js 文件,添加了两个切面方法的同时,保证每个方法都添加了 startend 事件。这样再调用的时候便可直接在执行前后操作其他任务了。

三、总结与思考

其实上面的操作人工也可以直接操作,但是,将一切重复单一的工作交给程序,这或许是代码存在的真正意义。一个简单的例子或许能打开一个新的世界,虽然,每一行代码都是独一无二的,但是如果追本溯源,最初并且真切的思想却是相通的

以上就是详解使用抽象语法树AST实现一个AOP切面逻辑的详细内容,更多关于AST抽象语法树实现AOP的资料请关注脚本之家其它相关文章!

相关文章

  • 一文详解如何在IDEA中配置Node.js

    一文详解如何在IDEA中配置Node.js

    idea中支持运行很多种编程语言,只需要在电脑中安装好对应的语言环境,下面这篇文章主要给大家介绍了关于如何在IDEA中配置Node.js的相关资料,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2023-02-02
  • Node.js进程管理之进程集群详解

    Node.js进程管理之进程集群详解

    这篇文章介绍了Node.js进程管理之进程集群,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07
  • node版本快速切换及管理方法

    node版本快速切换及管理方法

    这篇文章主要为大家介绍了node版本快速切换及管理方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • package-lock.json解决依赖的版本管理使用详解

    package-lock.json解决依赖的版本管理使用详解

    这篇文章主要为大家介绍了package-lock.json解决依赖的版本管理使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • 如何使用Node写静态文件服务器

    如何使用Node写静态文件服务器

    这篇文章主要介绍了如何使用Node写静态文件服务器,文章围绕主题展开详细的内容介绍,具有一定的参考价值,感兴趣的小伙伴可以参考一下
    2022-09-09
  • Elasticsearch插件及nodejs的安装配置

    Elasticsearch插件及nodejs的安装配置

    这篇文章主要为大家介绍了Elasticsearch插件及nodejs的安装配置,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-04-04
  • 使用Node.js搭建Web服务器

    使用Node.js搭建Web服务器

    这篇文章介绍了使用Node.js搭建Web服务器的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • 前端node Session和JWT鉴权登录示例详解

    前端node Session和JWT鉴权登录示例详解

    关于前端鉴权登录是比较常见的需求了,本文将从服务端渲染和前后端分离的不同角度下演示鉴权,为大家介绍前端node Session和JWT鉴权登录示例详解
    2022-07-07
  • Koa2框架快速入门与基本使用方式

    Koa2框架快速入门与基本使用方式

    这篇文章主要介绍了Koa2框架快速入门与基本使用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • nodejs多版本管理总结

    nodejs多版本管理总结

    这篇文章主要介绍了nodejs多版本管理的相关知识点,以及实际操作方法和代码,有需要的朋友参考下。
    2018-04-04

最新评论