之前用了接近hack的方式实现了console的封装,目标是获取console.log函数的执行(调用栈所在位置)所在的代码行数。
例如以下代码,执行window.mylog(1)时候,console.log实际是在匿名的箭头函数()=>{//这里执行的}
const mylog = (...arg) => console.log(...arg)
mylog("window.mylog")
如果代码改为以下,
const mylog2={
log:console.log
}
mylog2.log("test")
因为log返回的是conosle.log本身,并且它并没有在函数内执行,这里理解把console.log这个函数的内存地址赋值给mylog2.log,执行mylog2.log就是执行console.log
调试1
用谷歌调试工具,断点来查看演示上面效果:
mylog:
mylog2:
再次调试:
代码:
const mylog = () => {
return {
logx: (...arg) => {
return console.log(...arg)
}
}
}
const mylog2 = () => {
return {
logx: console.log
}
}
const MyLog = mylog();
const MyLog2 = mylog2();
MyLog.logx("window.mylog")
MyLog2.logx("window.mylog2")
效果:
调试:
结果:
mylog.logx执行的函数就是logx,而mylog2.logx执行的是console.log函数
封装hooks
const useConsole = function (...arg) {
window.console.log("outside", this)
return {
log: window.console.log,
warn: window.console.log,
}
}
使用:
const Console = useConsole();
Console.log(111, 6666, 222)
Console.warn(111, 6666, 222)
Console.test(111, 6666, 222)
上面代码,vue,react,和script标签内都适用
弊端
打包发布时候,压缩代码插件无法移除Console.log或者Console.warn,需要手动配置,例如uglifyjs-webpack-plugin 就是配置pure_funcs属性
// 引入uglifyjs-webpack-plugin
const UglifyPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
configureWebpack: (config) => {
let optimization = {
minimizer: [new UglifyPlugin({
// 删除console
uglifyOptions: {
parallel: true,
warnings: false,
compress: {
drop_console: false, //是否清除所有console
drop_debugger: true,//是否清除debugger
pure_funcs: ['Console.log','Console.warn'] //drop_console 设置false,需要特殊清除的
}
}
})]
}
Object.assign(config, {
optimization
})
}
}