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

Sea*_*son 75 javascript logging

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

window.console && console.log("Foo");
Run Code Online (Sandbox Code Playgroud)

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

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

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

cra*_*igb 48

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

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

你明白了...在控制台的各种实现上定义了很多功能,所以你可以将它们全部或只是你使用的那些(例如,如果你只使用console.log和从未使用过console.profile,console.time等等).

这对我来说是一个更好的选择,而不是在每个调用前添加条件,或者不使用它们.

另请参阅:在您的producton JavaScript代码中调用"console.log()"调用是不是一个坏主意?

  • 好主意.只需要一些修复.Visual Studio JS调试器抛出第一个console.log = noOp(),因为未定义控制台对象本身.我是这样做的:console = {log:noOp,warn:noOp,error:noOp}.另请注意,您不希望在noOp之后放置() - 您希望分配函数本身而不是其返回值.在Visual Studio JS调试器和IE9上测试 - 现在它工作正常. (6认同)
  • 仅供参考,如果你已经在使用jQuery,它们会提供一个noop函数:`$ .noop`. (3认同)

Rob*_*b W 36

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

回答另一个问题:代码不能产生负面的副作用:

  • window.console如果console没有定义,将评估为false
  • console.log("Foo")将在定义时将消息打印到控制台(前提是页面不会console.log被非功能覆盖).

  • 我原则上同意你的意见.但是,我认为我们都同意实现除了在调试模式期间不会触发的日志记录对于高质量的服务器端代码是必要的.没有人通过并删除他们的生产版本的日志记录 - 该程序确定需要什么级别的日志记录并做出相应的反应.我希望有一些类似于客户端编程的东西......如果需要,甚至只需设置一个"isDebug"变量.为什么我要为将来的开发人员返回并重新添加有问题的区域的日志记录而给下一个开发人员带来负担? (38认同)
  • 破旧怎么样?我认为说开发者控制台是生产网站的一部分,就像说日志文件是应用程序的一部分.是的,它们都是由代码生成的,但应该有一定程度的理解,即日志必须留在某处.但是,日志中的语句是否是用户友好的是另一回事. (11认同)
  • 您可以标记每一段调试代码,例如通过注释前缀/后缀一行调试代码.示例:`/*DEBUG:start*/console.log("Foo");/*DEBUG:end*/`.然后,使用RegExp删除所有出现的`/*DENUG-start*/[\ S\s]*?/*DEBUG-end*/`.最小化器将删除剩余的空白字符. (6认同)
  • 如何在最小化之前自动剥离调试代码?客户端日志消息可以采用大量表单. (4认同)
  • 有人听说过开发者控制台吗?如果我们只是用那个奇妙的工程进行调试而不是在代码周围放置 console.whatever 会怎样?/*DEBUG:start*/ => wtffff 是这个吗?如果我认识你,我会解雇你... (2认同)
  • 除非此答案说明为什么不应该这样做,否则它实际上没有用。我们只是在没有证据或理由的情况下盲目接受它是不好的? (2认同)
  • @Juan 有很多理由在开发中使用控制台日志记录,特别是为不处理代码或不是前端工程师的人员记录错误和警告。 (2认同)
  • @ThomasMcCabe我同意,如果需要显示用户应该在控制台中看到的消息或错误,那么使用它。但是,如果您在编写函数来“测试”某些变量的值时使用它,因为您不知道如何放置断点,那么就会出现问题。如果您提交并忘记删除它,情况会更糟。 (2认同)

ter*_*les 28

UglifyJS2

如果您使用此缩小器,则可以设置drop_console选项:

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

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

  • 如果您正在使用_grunt_和_uglify_,也可以使用相同的选项(似乎uglify基于UglifyJS2):https://github.com/gruntjs/grunt-contrib-uglify#turn-off-console-warnings (3认同)
  • 问题是“我应该”,而不是“我该怎么做”。 (2认同)

wut*_*utz 16

如果缩小是构建过程的一部分,您可以使用它去除调试代码,如此处使用Google闭包编译器所述:在缩小过程中排除调试JavaScript代码

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

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


Mar*_*o B 7

不要让事情过于复杂化!我个人在开发过程中一直使用console.log,它非常节省时间。对于生产,我只需添加一行代码(在我的例子中的“生产配置文件”中)即可禁用所有日志:

window.console.log = () => {};
Run Code Online (Sandbox Code Playgroud)

完成;)这只猴子修补了window.console并将日志函数替换为空函数,从而禁用输出。

在大多数情况下,这对我来说已经足够了。如果您想“一路”并从代码中删除 console.logs 以减少捆绑包大小,则必须更改 js 的捆绑方式(例如使用 minifier 或其他方式删除 console.logs )

另外,我认为你实际上可以充分表明将它们留在其中 - 即使在生产中也是如此。对于普通用户来说,它不会改变任何东西,但确实可以加快理解奇怪的“异国浏览器”问题。它不像可能包含关键信息的后端日志。无论如何,您甚至可以通过 console.log 显示的所有内容显然都已经在前端可用了!不显示日志消息,因为您害怕透露安全详细信息或类似的东西,这实际上只是“默默无闻的安全”,并且应该让您思考为什么这些信息甚至可以在前端上使用!只是我的观点。


MK_*_*Dev 5

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

  • 现在是 2019 年了。我怀疑是否有任何浏览器不支持控制台。 (3认同)

Zac*_*bey 5

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

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

这是我最近用来解决这个困境的一些代码的一小段。它修复了由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);
}
Run Code Online (Sandbox Code Playgroud)

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

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