【问题标题】:Override console.log(); for production [duplicate]覆盖 console.log();用于生产 [重复]
【发布时间】:2011-10-25 22:28:44
【问题描述】:

我对 Javascript 开发还很陌生,所以这可能是一个真正的新手问题。

我有一个带有console.log(); 应用程序,用于调试目的。

我有 完成我所有的构建时间组合。它输出一个app.debug.js 用于调试以及一个app.min.js 用于生产

现在我可以浏览所有代码文件以查找 console.log(); 并在准备投入生产时手动删除它,但我想知道是否有办法覆盖该方法。

基本上,每当调用 console.log(); 方法时,什么都不做。

这样,我可以将覆盖代码文件放在我的生产配置中,而不是放在我的调试配置中。

这可能吗?

【问题讨论】:

  • 使用log 函数创建您自己的名称为console 的对象,该函数什么都不做/只做函数定义。
  • 这是覆盖console.log函数的好方法,但保留函数的原始功能...udidu.blogspot.co.il/2012/12/override-console-functions.html
  • Chase -- 你能告诉我我的重复关闭是否错误吗? (然后我可以反转)
  • 我可以推荐picolog吗?它超小,可在浏览器、nodejs 和 Nashorn 中运行,支持 Nodejs 控制台 API(因此可以轻松放入以替换普通控制台)并接受来自查询字符串(浏览器)或环境变量 PICOLOG_LEVEL 的日志记录级别。免责声明:我是作者。我专门写了它,因为我厌倦了必须选择是否包含一些大型日志库,或者围绕对控制台的访问编写测试等。我最终在每个项目中重新实现了相同的东西,所以我创建了这个库。

标签: sencha-touch chirpy javascript debugging


【解决方案1】:

能够在生产版本中切换日志记录会非常有用。下面的代码默认关闭记录器。

当我需要查看日志时,我只需在控制台中输入debug(true)

var consoleHolder = console;
function debug(bool){
    if(!bool){
        consoleHolder = console;
        console = {};
        Object.keys(consoleHolder).forEach(function(key){
            console[key] = function(){};
        })
    }else{
        console = consoleHolder;
    }
}
debug(false);

为了彻底,这会覆盖所有控制台方法,而不仅仅是console.log

【讨论】:

  • 工作正常,但删除行 consoleHolder = console;当 bool = false 行号时。 4. 因为这行代码在连续两次调用debug(false)时禁用了这个功能。如果我们已经调用了 debug(false);debug(false); 我们不能再次调用 debug(true)意味着两次
【解决方案2】:

或者如果你只是想重新定义控制台的行为(例如为了添加日志) 你可以这样做:

// define a new console
var console=(function(oldCons){
    return {
        log: function(text){
            oldCons.log(text);
            // Your code
        },
        info: function (text) {
            oldCons.info(text);
            // Your code
        },
        warn: function (text) {
            oldCons.warn(text);
            // Your code
        },
        error: function (text) {
            oldCons.error(text);
            // Your code
        }
    };
}(window.console));

//Then redefine the old console
window.console = console;

【讨论】:

  • 非常好...因为这些控制台方法接受多个参数,但我们可以通过调用 oldCons.log.apply(arguments)
  • @python1981,或者我们可以使用 ES6 扩展运算符。
【解决方案3】:

当 url 不包含 localhost 时,这将覆盖 console.log 函数。您可以使用自己的开发设置替换 localhost。

// overriding console.log in production
if(window.location.host.indexOf('localhost:9000') < 0) {
    console.log = function(){};
}

【讨论】:

  • 聪明,但这种方法有很多额外的开销。在部署过程中更改脚本是一个更好的解决方案。使用某种自动部署工具来注入在accepted answer 中找到的代码,这样如果检查就为零。
【解决方案4】:

这就是我所做的

    var domainNames =["fiddle.jshell.net"]; // we replace this by our production domain.

var logger = {
    force:false,
    original:null,
    log:function(obj)
    {
        var hostName = window.location.hostname;
        if(domainNames.indexOf(hostName) > -1)
        {
            if(window.myLogger.force === true)
            {
                window.myLogger.original.apply(this,arguments);
            }
        }else {
            window.myLogger.original.apply(this,arguments);
        }
    },
    forceLogging:function(force){
        window.myLogger.force = force;
    },
    original:function(){
        return window.myLogger.original;
    },
    init:function(){
        window.myLogger.original = console.log;
        console.log = window.myLogger.log;
    }
}

window.myLogger = logger;
console.log("this should print like normal");
window.myLogger.init();
console.log("this should not print");
window.myLogger.forceLogging(true);
console.log("this should print now");

也在这里发布。 http://bhavinsurela.com/naive-way-of-overriding-console-log/

【讨论】:

    【解决方案5】:

    看了很多帖子,我自己的解决方法如下:

    脚本:

    function extendConsole() {
        "use strict";
        try {
            var disabledConsoles = {};
    
            console.enable = function (level, enabled) {
                // Prevent errors in browsers without console[level]
                if (window.console === 'undefined' || !window.console || window.console === null) {
                    window.console = {};
                }
                if (window.console[level] === 'undefined' || !window.console[level] || window.console[level] == null) {
                    window.console[level] = function() {};
                }
    
                if (enabled) {
                    if (disabledConsoles[level]) {
                        window.console[level] = disabledConsoles[level];
                    }
                    console.info("console." + level + "() was enabled.");
                } else {
                    disabledConsoles[level] = window.console[level];
                    window.console[level] = function () { };
                    console.info("console." + level + "() was disabled.");
                }
            };
        } catch (exception) {
            console.error("extendConsole() threw an exception.");
            console.debug(exception);
        }
    }
    

    用法:

    extendConsole();
    console.enable("debug", window.debugMode);
    

    示例:

    http://jsfiddle.net/rodolphobrock/2rzxb5bo/10/

    【讨论】:

      【解决方案6】:

      我建议使用:https://github.com/sunnykgupta/jsLogger

      特点:

      1. 它安全地覆盖了 console.log。
      2. 请注意控制台是否不可用(哦,是的,您也需要考虑这一点。)
      3. 存储所有日志(即使它们被禁止)以供以后检索。
      4. 处理主要的控制台功能,如logwarnerrorinfo

      开放供修改,并会在出现新建议时更新。

      免责声明:我是插件的作者。

      【讨论】:

      • 看起来真不错!我喜欢以后有日志列表的想法。作为一个建议(虽然很简单),更多文档可能对您的 README 有用
      【解决方案7】:

      把它放在文件的顶部:

      var console = {};
      console.log = function(){};
      

      对于某些浏览器和缩小器,您可能需要将其应用于窗口对象。

      window.console = console;
      

      【讨论】:

      • 不要忘记覆盖console.infoconsole.warnconsole.error,如果你使用它们
      • @Flambino,我以前从未使用过console.info。看看他们每个人的输出,他们“看起来”是一样的......你会说loginfo之间的区别是什么?
      • FWIW,控制台原型上还有很多其他功能,虽然其中很多很少使用。从 Chrome 38 开始:assertclearconstructorcountdebugdirdirxmlerrorgroupgroupEnd8、@98765433@8@、 987654340 @,logmarkTimelineprofileprofileEndtabletimetimeEndtimeStamptimelinetimelineEndtracewarn .
      • 虽然这是一个投票率很高的答案,但我不推荐它,它会覆盖整个控制台对象,而不是只覆盖日志函数。
      • 我在下面的回答解决了对整个控制台对象进行核对而不是覆盖每个方法的问题。它也很灵活,因为它实际上并不知道可用的方法。它只是替换了控制台对象上的所有方法。这是未来的证明。
      【解决方案8】:

      没有理由让所有 console.log 在 prod 环境中遍布您的项目...如果您想以正确的方式执行此操作,请使用“drop_console”选项将UglifyJS2 添加到您的部署过程中。

      【讨论】:

      • 放弃控制台调用而不是将它们保留在错误上下文中并不是很好。虽然我可以理解您为什么要这样做,但如果您没有适当的错误和日志管理
      • 如果我设置了一个特定的 cookie/header,调试模式将被启用并加载未缩小的 js(服务器静态也记录在浏览器控制台上)。
      • 只是备注,requirejs中的uglify2没有这个选项:o
      【解决方案9】:

      我使用类似于 posit labs 的东西。将控制台保存在一个闭包中,您就可以在一个可移植的功能中拥有一切。

      var GlobalDebug = (function () {
          var savedConsole = console;
          return function(debugOn,suppressAll){
              var suppress = suppressAll || false;
              if (debugOn === false) {
                  console = {};
                  console.log = function () { };
                  if(suppress) {
                      console.info = function () { };
                      console.warn = function () { };
                      console.error = function () { };
                  } else {
                      console.info = savedConsole.info;
                      console.warn = savedConsole.warn;
                      console.error = savedConsole.error;              
                  }
              } else {
                  console = savedConsole;
              }
          }
      })();
      

      只需执行 globalDebug(false) 即可关闭日志消息,或者执行 globalDebug(false,true) 即可删除所有控制台消息。

      【讨论】:

      • 正是我想要的,不仅可以禁用日志,还可以通过浏览器本身启用它。
      • 完美运行!
      【解决方案10】:

      如果不再需要,您还可以使用正则表达式删除代码中的所有 console.log() 调用。任何体面的 IDE 都允许您在整个项目中搜索和替换这些内容,并允许您在提交更改之前预览匹配项。

      \s*console\.log\([^)]+\);
      

      【讨论】:

      • 感谢您的反对。我正在回答这部分问题。 “我可以浏览所有代码文件以查找 console.log();并在我准备好投入生产时手动删除它”
      • 会匹配console.log("update() function called");吗?
      • 不,很遗憾没有。如果您不希望日志后跟任何其他代码,可以使用以下代码:\s*console\.log(.+);但这风险更大。
      • 我的意思是当消息中有)时它会失败。
      【解决方案11】:

      您可以查看UglifyJS: http://jstarrdewar.com/blog/2013/02/28/use-uglify-to-automatically-strip-debug-messages-from-your-javascript/, https://github.com/mishoo/UglifyJS 我还没试过。

      引用,

       if (typeof DEBUG === 'undefined') DEBUG = true; // will be removed
      
       function doSomethingCool() {
           DEBUG && console.log("something cool just happened"); // will be removed }
      

      ...日志消息行将被 Uglify 的死代码移除器移除 (因为它将删除任何将始终评估为的条件 错误的)。第一个条件也是如此。但是当你测试为 未压缩的代码,DEBUG 会从 undefined 开始,第一个 条件将其设置为 true,并且您的所有 console.log() 消息 会工作的。

      【讨论】:

        【解决方案12】:

        请记住,使用此方法,每个 console.log 调用仍会调用一个(空)函数,从而导致开销,如果有 100 个 console.log 命令,您仍然会调用 100 个空白函数。

        不确定这会导致多少开销,但会有一些开销,最好有一个标志来打开调试,然后使用类似以下内容的东西:

        var debug=true; if (debug) console.log('blah')
        

        【讨论】:

        • 这将涉及遍历所有代码并添加那些 if 语句——这很乏味。
        • 它确实需要更多的代码,但这种技术有其优点:debug 可以在运行时切换;并且当debug 为假时,没有低效的字符串构建将立即被丢弃。因此,开发人员可以编写大量日志记录,而不会影响生产性能,但如果他们真的需要,仍然可以从客户那里获取这些信息。
        • 运行时切换很有用。
        • 很好的建议,虽然从技术上讲不是问题的答案。我仍然认为这个答案应该得到更多的选票,因为在 Javascript 中不推荐使用覆盖本机对象的做法。其他脚本可能会使用控制台。它实际上有很多功能,你在替换它时会丢弃它。
        • 实际上,如果将其与 uglify --compress 结合使用,这将是一个真正的答案。也可以更快地使用DEBUG &amp;&amp; console.log(...。优点是代码会被删除(死代码),缺点:繁琐
        【解决方案13】:
        console.log = function(){};
        

        像其他任何东西一样覆盖它。

        【讨论】:

        • -1。不要这样做!此处的行将在不存在 console 对象的浏览器上抛出 ReferenceError 并保留 console.log 未定义,这对于至少某些版本的 IE 来说是一个问题。如果您的目标是让您的 Web 应用程序像 OP 一样投入生产,那么这几乎不是您需要的解决方案。做尼尔写的。
        • @MarkAmery 你是对的。我把“覆盖”的字面意思理解为“替换”,所以我当然假设存在原件。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-06-03
        • 1970-01-01
        • 2021-11-08
        • 2012-02-16
        • 2016-12-19
        • 2016-12-16
        • 2020-07-23
        相关资源
        最近更新 更多