• 中文
  • ENGLISH
浅谈web前端调试日志
2015/09/01

现在前端开发使用console.log是最常见的调试方式之一,在控制台能很方便的看到程序执行日志,但存在几个问题:
1. 并不是所有的浏览器都有console对象,比如IE6-IE7本身是没有开发控制台的,除非自己安装IE Dev toolbar,IE8自带DevToolbar,但如果不开启,console是undefined,会导致浏览器报错。
2. console.log本身是打出程序执行日志,这些信息本身是用于调试,发布到线上之后是否需要清除掉?

我们先看第一个问题

1.使用前先判断

使用console.log的时候需要先判断console是否是对象,并且console.log是否是方法

if(!!console && typeof console.log === "function"){
    console.log("here is log message");
}

2.抽象成函数

但每次都这么用,势必很复杂,所以可以抽象成自己的函数,比如:

function myLog(message){
   if(!!console && typeof console.log === "function"){
      console.log(message || "");
   }
}

myLog("here is log message");

这样做的缺点有几个,一个是用自己的函数去替换console.log这种深入人心的代码,在落地执行上多少都有些困难,尤其是团队越大,越有人不遵循规范。另外,在控制台打出日志的代码行数提示时,总提示myLog那一行,而不是真正的代码逻辑行。

3.还有种方案,在JS初始化的时候对console做一次判断,防止出错。

比如:

(function(con) {
  'use strict';
  var prop, method;
  var empty = {};
  var dummy = function() {};
  var properties = 'memory'.split(',');
  var methods = ('assert,clear,count,debug,dir,dirxml,error,exception,group,' +
     'groupCollapsed,groupEnd,info,log,markTimeline,profile,profiles,profileEnd,' +
     'show,table,time,timeEnd,timeline,timelineEnd,timeStamp,trace,warn').split(',');
  while (prop = properties.pop()) con[prop] = con[prop] || empty;
  while (method = methods.pop()) con[method] = con[method] || dummy;
})(this.console = this.console || {});

对于第二个问题

发布时如何去掉console.log的调试信息,保证线上环境的干净,也两种方案。

1.使用grunt插件grunt-removing-log

插件地址:https://github.com/ehynds/grunt-remove-logging
该插件可以自动去除console.log这样的代码,可以在实际项目中,debug模式不启用,而build模式启用。

2.使用grunt插件grunt-contrib-uglifyConditional compilation

grunt-contrib-uglify插件可以配置类似条件编译的特性:

grunt.initConfig({
  uglify: {
    options: {
      compress: {
        global_defs: {
          "DEBUG": false
        },
        dead_code: true
      }
    },
    my_target: {
      files: {
        'dest/output.min.js': ['src/input.js']
      }
    }
  }
});

详情参考 https://github.com/gruntjs/grunt-contrib-uglify

3.使用URL参数控制是否输出日志

这个需要配合第一个点,自行去定义console.log的含义。需要判断URL是否有debug=true这样的参数,如果有,则执行console.log,否则可以让console.log指向到空函数。
案例: 国内某视频网站就是全站URL加入debug=true,都可以看到调试日志,好处是方便开发快速定位问题,但缺点是如果用户知道,那么可能会泄露不该有的信息,不过…JS本身明文的,而且还可以抓包,这些问题不大。

订阅我们