用proxy改造你的console

10,910 阅读1分钟

前言

在前端平常的开发中,最长使用的调试手段应该就是console大法。console很好用,但有时候打印变量多了,看起来就比较懵。

let name1 = 'kk'; name2 = 'kkk'; name3 = 'kk1k'; name4= 'k1kk';
console.log(name1)
console.log(name2)
console.log(name3)
console.log(name4)

打印如下 image.png

那个变量 对应那个 就比较难分辨。我又不想在写代码来分辨(懒😀),那个打印对应的变量是多少。

解决方案

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

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

实践

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

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-consoles 感兴趣的可以试试,有bug记得跟我说(●'◡'●)

源码地址: github.com/ALiangTech/…