Javascript 我应该从生产代码中删除 console.log 吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8002116/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 04:20:37  来源:igfitidea点击:

Should I be removing console.log from production code?

javascriptlogging

提问by Sean Anderson

I currently have this JS statement everywhere in my code:

我目前在我的代码中到处都有这个 JS 语句:

window.console && console.log("Foo");

I am wondering if this is costly at all, or has any negative side-effects in production.

我想知道这是否成本高昂,或者对生产有任何负面影响。

Am I free to leave client-side logging in, or should it go?

我可以自由地离开客户端登录,还是应该离开?

EDIT: In the end, I suppose the best argument I (and anyone else?) can come up with is that there is a possibly non-negligible amount of extra data transferred between the server and the client by leaving logging messages left in. If production code is to be fully optimized, logging will have to be removed to reduce the size of javascript being sent to the client.

编辑:最后,我想我(和其他任何人?)能提出的最好论点是,通过保留日志消息,在服务器和客户端之间传输的额外数据量可能不可忽略。如果生产代码要完全优化,必须删除日志记录以减少发送到客户端的 javascript 的大小。

采纳答案by Rob W

You should notadd development tools to a production page.

你应该开发工具添加到生产页面。

To answer the other question: The code cannot have a negative side-effect:

回答另一个问题:代码不能有负面影响:

  • window.consolewill evaluate to false if consoleis not defined
  • console.log("Foo")will print the message to the console when it's defined (provided that the page does not overwrite console.logby a non-function).
  • window.console如果console未定义,将评估为 false
  • console.log("Foo")将在定义时将消息打印到控制台(前提是页面不会console.log被非功能覆盖)。

回答by craigb

Another way of dealing with this is to 'stub' out the console object when it isn't defined so no errors are thrown in contexts that do not have the console i.e.

解决此问题的另一种方法是在控制台对象未定义时将其“存根”,以便在没有控制台的上下文中不会抛出任何错误,即

if (!window.console) {
  var noOp = function(){}; // no-op function
  console = {
    log: noOp,
    warn: noOp,
    error: noOp
  }
}

you get the idea... there are a lot of functions defined on the various implementations of the console, so you could stub them all or just the ones you use (e.g. if you only ever use console.logand never used console.profile, console.timeetc...)

你明白了……在控制台的各种实现上定义了很多函数,所以你可以存根它们全部或只是你使用的那些(例如,如果你只使用过console.log而从未使用过console.profileconsole.time等等......)

This for me is a better alternative in development than adding conditionals in front of every call, or not using them.

对我来说,这比在每次调用前添加条件或不使用它们更好的选择。

see also: Is it a bad idea to leave "console.log()" calls in your producton JavaScript code?

另请参阅:在您的产品中保留 JavaScript 代码中的“console.log()”调用是否是一个坏主意?

回答by terales

UglifyJS2

丑化JS2

If you are using this minifier, you can set drop_consoleoption:

如果您正在使用此压缩器,则可以设置drop_console选项

Pass true to discard calls to console.* functions

传递 true 以放弃对 console.* 函数的调用

So I would suggest to leave console.logcalls as they are for a most trickiest part of the codebase.

所以我建议保留 console.log调用,因为它们是代码库中最棘手的部分。

回答by wutz

If minification is part of your build process, you may use it to strip out debug code, as explained here with Google closure compiler: Exclude debug JavaScript code during minification

如果缩小是您的构建过程的一部分,您可以使用它来去除调试代码,如谷歌闭包编译器所解释的:在缩小期间排除调试 JavaScript 代码

if (DEBUG) {
  console.log("Won't be logged if compiled with --define='DEBUG=false'")
}

If you compile with advanced optimizations, this code will even be identified as dead and removed entirely

如果您使用高级优化进行编译,此代码甚至会被识别为死并完全删除

回答by MK_Dev

Yes. console.log will throw an exception in browsers that don't have support for it (console object will not be found).

是的。console.log 将在不支持它的浏览器中抛出异常(将找不到控制台对象)。

回答by Zach Lysobey

Generally yes, its not a great idea to expose log messages in your production code.

通常是的,在生产代码中公开日志消息不是一个好主意。

Ideally, you should remove such log messages with a build script before deployment; but many (most) people do not use a build process (including me).

理想情况下,您应该在部署之前使用构建脚本删除此类日志消息;但是许多(大多数)人不使用构建过程(包括我)。

Here's a short snippet of some code I've been using lately to solve this dilemma. It fixes errors caused by an undefined consolein old IE, as well as disabling logging if in "development_mode".

这是我最近用来解决这个困境的一些代码的一小段。它修复了由console旧 IE 中的 undefined 引起的错误,以及在“development_mode”中禁用日志记录。

// fn to add blank (noOp) function for all console methods
var addConsoleNoOp =  function (window) {
    var names = ["log", "debug", "info", "warn", "error",
        "assert", "dir", "dirxml", "group", "groupEnd", "time",
        "timeEnd", "count", "trace", "profile", "profileEnd"],
        i, l = names.length,
        noOp = function () {};
    window.console = {};
    for (i = 0; i < l; i = i + 1) {
        window.console[names[i]] = noOp;
    }
};

// call addConsoleNoOp() if console is undefined or if in production
if (!window.console || !window.development_mode) {
    this.addConsoleNoOp(window);
}

I'm pretty sure I took much of the above addConsoleNoOpf'n from another answer on SO, but cannot find right now. I'll add a reference later if I find it.

我很确定我addConsoleNoOp从关于 SO 的另一个答案中获取了上面的大部分内容,但现在找不到。如果我找到它,我会在以后添加参考。

edit: Not the post I was thinking of, but here's a similar approach: https://github.com/paulmillr/console-polyfill/blob/master/index.js

编辑:不是我想到的帖子,但这里有一个类似的方法:https: //github.com/paulmillr/console-polyfill/blob/master/index.js

回答by dynamiclynk

var AppLogger = (function () {
  var debug = false;
  var AppLogger = function (isDebug) {
    debug = isDebug;
  }
  AppLogger.conlog = function (data) {
    if (window.console && debug) {
        console.log(data);
    }
  }
  AppLogger.prototype = {
    conlog: function (data) {
        if (window.console && debug) {
            console.log(data);
        }
    }
  };
return AppLogger;
})();

Usage:

用法:

var debugMode=true;
var appLogger = new AppLogger(debugMode);
appLogger.conlog('test');

回答by ilyaigpetrov

TL;DR

TL; 博士

Idea:Logging objects precludes them from being Garbage Collected.

想法:记录对象阻止它们被垃圾收集。

Details

细节

  1. If you pass objects to console.logthen these objects are accessible by reference from console of DevTools. You may check it by logging object, mutating it and finding that old messages reflect later changes of the object.
  2. If logs are too long old messages do get deleted in Chrome.
  3. If logs are short then old messages are not removed, if these messages reference objects then these objects are not Garbage Collected.
  1. 如果您将对象传递给console.log这些对象,那么这些对象可以通过 DevTools 控制台的引用来访问。您可以通过记录对象、改变它并发现旧消息反映对象的后续更改来检查它。
  2. 如果日志太长,旧消息会在 Chrome 中被删除。
  3. 如果日志很短,则不会删除旧消息,如果这些消息引用对象,则这些对象不是垃圾收集的。

It's just an idea:I checked points 1 and 2 but not 3.

这只是一个想法:我检查了第 1 点和第 2 点,但没有检查第 3 点。

Solution

解决方案

If you want to keep logs for sake of client-side troubleshooting or other needs then:

如果您想保留日志以用于客户端故障排除或其他需要,则:

['log', 'warn', 'error'].forEach( (meth) => {
  const _meth = window.console[meth].bind(console);
  window.console[meth] = function(...args) { _meth(...args.map((arg) => '' + arg)) }
});

回答by shanky

Yes, its good practice to use console.logfor javascript debugging purpose, but it needs to be removed from the production server or if needed can be added on production server with some key points to be taken into consideration:

是的,console.log用于 javascript 调试目的的好习惯,但它需要从生产服务器中删除,或者如果需要可以添加到生产服务器上,并考虑一些关键点:

**var isDebugEnabled="Get boolean value from Configuration file to check whether debug is enabled or not".**
if (window.console && isDebugEnabled) {
    console.log("Debug Message");
}

Above code block has to be used everywhere for logging in order to first verify whether the console is supported for the current browser and whether debug is enabled or not.

为了首先验证当前浏览器是否支持控制台以及是否启用调试,必须在任何地方使用上面的代码块进行日志记录。

isDebugEnabledhas to be set as true or false based on our environment.

isDebugEnabled必须根据我们的环境设置为 true 或 false。

回答by Kyle Coots

I know this is quite an old question and hasn't had much activity in a while. I just wanted to add my solution that I came up with which seems to work quite well for me.

我知道这是一个很老的问题,并且已经有一段时间没有太多活动了。我只是想添加我想出的解决方案,这似乎对我来说效果很好。

    /**
     * Logger For Console Logging 
     */
    Global.loggingEnabled = true;
    Global.logMode = 'all';
    Global.log = (mode, string) => {    
        if(Global.loggingEnabled){
            switch(mode){
              case 'debug':
                  if(Global.logMode == 'debug' || Global.logMode == 'all'){
                    console.log('Debug: '+JSON.stringify(string));
                  }
                  break;
              case 'error':
                  if(Global.logMode == 'error' || Global.logMode == 'all'){
                    console.log('Error: '+JSON.stringify(string));
                  }       
                  break;
              case 'info':
                  if(Global.logMode == 'info' || Global.logMode == 'all'){
                    console.log('Info: '+JSON.stringify(string));
                  }
                  break;
            }
        }
    }

Then I typically create a function in my scripts like this or you could make it available in a global script:

然后我通常会在我的脚本中像这样创建一个函数,或者您可以在全局脚本中使用它:

Something.fail = (message_string, data, error_type, function_name, line_number) => {
    try{

        if(error_type == undefined){
            error_type = 'error';
        }

        Global.showErrorMessage(message_string, true);
        Global.spinner(100, false);

        Global.log(error_type, function_name);
        Global.log(error_type, 'Line: '+line_number);
        Global.log(error_type, 'Error: '+data);

    }catch(error){
        if(is_global){
            Global.spinner(100, false);
            Global.log('error', 'Error: '+error);
            Global.log('error', 'Undefined Error...');
        }else{
            console.log('Error:'+error);
            console.log('Global Not Loaded!');
        }           
    }   
}

And then I just use that instead of console.log like this:

然后我只是使用它而不是像这样的 console.log :

try{
 // To Do Somehting
 Something.fail('Debug Something', data, 'debug', 'myFunc()', new Error().lineNumber);
}catch(error){
 Something.fail('Something Failed', error, 'error', 'myFunc()', new Error().lineNumber);
}