跳至主要內容

用proxy改造你的console

知识库编程技巧VUE应用VUE应用大约 1 分钟

解决方案

方案一,通过ast解析console 将变量名放在console后面,奈何esbuild不支持ast操作(不是我不会 哈哈哈哈), 故放弃。

方案二,既然vue能代理对象,那么console是不是也能被代理。

实践

第一步代理console,将原始的console,用全局变量originConsole保存起来,以便后续使用 withLogging 函数拦截console.log 重写log参数

js复制代码const originConsole = window.console; 
var console = new Proxy(window.console, { 
    get(target, property) { 
    if(property === 'log') { 
        return withLogging(target[property]) 
    } 
    return target[property] }, 
})

遇到问题,js中 无法获取获取变量的名称的字符串。就是说无法打印变量名。

解决方案,通过vite中的钩子函数transform,将console.log(name.x) 转化成 console.log(name.x, ['isPlugin', 'name.x'])

transform(src, id) {
    if(id.includes('src')) { // 只解析src 下的console
        const matchs = src.matchAll(/console.log\((.*)\);?/g);
        [...matchs].forEach((item) => {
                const [matchStr, args] = item;
                let replaceMatch = ''
                const haveSemicolon = matchStr.endsWith(";"); 
                const sliceIndex = haveSemicolon ? -2 : -1;
                const temp = matchStr.slice(0,sliceIndex); 
                const tempArgs = args.split(",").map(item => {
                    if(item.endsWith('"')) {
                        return item
                    }
                    return `"${item}"`
                }).join(",")
                replaceMatch = `${temp},['isPlugin',${tempArgs}]);`
                src = src.replace(matchStr, replaceMatch)
        });
    }
    return {
      code: src,
      id,
    }
},

这样最终就实现了类型于这样的输出代码

originConsole.log('name.x=', name.x)

这样也就最终实现了通过变量输出变量名跟变量值的一一对应

最后

我将其写成了一个vite插件,vite-plugin-consolesopen in new window 感兴趣的可以试试,有bug记得跟我说(●'◡'●)

源码地址: github.com/ALiangTech/…open in new window