注册
web

用proxy改造你的console

前言


在前端平常的开发中,最长使用的调试手段应该就是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/…


作者:平平无奇的阿良
来源:juejin.cn/post/7238508573667344441

0 个评论

要回复文章请先登录注册