重写console方法?

527 阅读2分钟

问题

前端工程是基于VUE CLI3来初始化的,内置webpack4,打包生成的app.xxxxxx.js文件中console.log(xxx)是存在的,但浏览器控制台没有。

注:

本地启动相同浏览器控制台是有输出的。

疑惑

线上是直接引用构建的文件,既然日志信息在最终打包的文件中存在,那线上访问应该有;

本地启动可以看到日志信息,就排除了浏览器本身的影响;

我们都知道,当需要去掉日志信息的时候,会通过webpack配置来完成,在构建的过程中删除:

const TerserWebpackPlugin = require('terser-webpack-plugin')
...
module.exports = {
  configureWebpack: {
    plugins: [
      new TerserPlugin({
        terserOptions: {
          compress: {
            drop_console: true,
            pure_funcs: ['console.log']
          }
        }
      })
    ]
  }
}

默认是不删除的,如果你想将所有console都删除,那只需要加:drop_console: true,但如果你仅仅需要去掉console.log,而console.infoconsole.error等不删除,那就加上配置pure_funcs: ['console.log'],这时候drop_console: true配置要去掉,因为它会全删。

尝试

console.error

既然console.logconsole.info都显示不了,在同一个位置新增console.error,效果符合预期:

image.png

google了一下,都说是级别问题,但信息这项是有勾选的,但还是显示不了。

Chrome DevTools

抛开项目,简单粗暴一点,在线上项目页面打开DevTools,输入console.log

image.png

用本地项目对比:

image.png

什么鬼?我不懂了。看来与代码无关,还是与浏览器有关。

本地和线上主要的区别在于开发和生产模式不同,难道和这个有关?

答案

漏了说一个项目背景,之所以没说,是因为我刚才以为与这个无关。我们整个项目是通过主项目加载子项目的,而我们是子项目。

问题是什么呢?

我把主项目main.js文件的一段代码贴出来,大家就明白了:

const win_log = console.log
const win_info = console.info
console.log = (...params) => {
  const enableLog = process.env.NODE_ENV === 'development' || (process.env.NODE_ENV !== 'development' && sessionStorage.enableLog)
  if (enableLog) {
    win_log(...params)
  }
}
console.info = (...params) => {
  const enableLog = process.env.NODE_ENV === 'development' || (process.env.NODE_ENV !== 'development' && sessionStorage.enableLog)
  if (enableLog) {
    win_info(...params)
  }
}

覆盖了loginfo方法。。。

也就是说在非开发环境,不加参数的情况下,Chrome devTools控制台不会打印这两个方法的信息了。

尝试解决

console.infowindow全局方法,被覆盖了。

那在子项目中先存储被覆盖的方法,然后再定义console.info方法,毕竟在主应用中是有判断的,在执行之前,先将enableLog设置为true,然后再调用。

尝试代码如下:

// 子项目 main.js
const win_info = console.info // 主应用定义
console.info = (...params) => {
  sessionStorage.enableLog = true
  win_info(...params)
}

在本地验证,没问题,正常输出。

部署到线上,有问题,没有输出。又是什么鬼!

查看了下主应用编译的代码,全是空。。

console.log = function() {}
console.info = function() {}