我应该从生产代码中删除console.log?
我目前在我的代码中有无处不在的JS语句:
window.console && console.log("Foo");
我想知道如果这是昂贵的,或者在生产中有任何消极的副作用。
我可以自由离开客户端login吗?还是应该离开?
编辑:最后,我想我最好的论据(和其他人?)可以拿出来是有一个可能不可忽视的额外的数据量在服务器和客户端之间留下日志留言留在。如果生产代码将被完全优化,日志将不得不被删除,以减less发送到客户端的JavaScript的大小。
您不应该将开发工具添加到生产页面。
要回答另一个问题:代码不能有负面的副作用:
- 如果未定义
console
则window.console
将评估为false -
console.log("Foo")
将在定义时将消息打印到控制台(前提是页面不会通过非函数覆盖console.log
)。
处理这个问题的另一种方法是在未定义控制台对象时“存根”,以便在没有控制台的上下文中引发错误
if (!window.console) { var noOp = function(){}; // no-op function console = { log: noOp, warn: noOp, error: noOp } }
你有这个想法…在控制台的各种实现中定义了很多函数,所以你可以把它们全部或只是你使用的那些(例如,如果你只使用console.log
使用console.profile
, console.time
等)
这对我来说是一个比在每个调用前添加条件都更好的替代方法,或者不使用它们。
另请参阅: 在producton JavaScript代码中保留“console.log()”调用是不是一个好主意?
UglifyJS2
如果您正在使用此缩小器,则可以设置drop_console
选项 :
通过真正的放弃调用控制台。*function
所以我会build议离开console.log
调用,因为它们是代码库中最棘手的部分。
如果缩小是构build过程的一部分,那么您可以使用它来去除debugging代码,如下面的Google封闭编译器所述: 在缩小过程中排除debuggingJavaScript代码
if (DEBUG) { console.log("Won't be logged if compiled with --define='DEBUG=false'") }
如果您使用高级优化进行编译,那么这个代码甚至会被确定为已经完全删除
是。 console.log将在不支持它的浏览器中引发exception(将不会find控制台对象)。
通常是的,在生产代码中公开日志消息并不是一个好主意。
理想情况下,您应该在部署之前使用构build脚本删除此类日志消息; 但许多(大多数)人不使用构build过程(包括我)。
以下是我最近用来解决这个难题的一些代码片段。 它修复了旧IE中未定义console
引起的错误,以及在“development_mode”中禁用日志logging的情况。
// 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); }
我敢肯定,我从上面的另一个答案上面的addConsoleNoOp
f'n大部分,但现在找不到。 如果我find它,我会在后面添加一个参考。
编辑:不是我正在考虑的职位,但这里有一个类似的方法: https : //github.com/paulmillr/console-polyfill/blob/master/index.js
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; })();
用法:
var debugMode=true; var appLogger = new AppLogger(debugMode); appLogger.conlog('test');
是的,它是使用console.log
进行javascriptdebugging的好习惯,但是需要从生产服务器上删除它,或者如果需要的话可以添加到生产服务器上,并考虑一些关键点:
**var isDebugEnabled="Get boolean value from Configuration file to check whether debug is enabled or not".** if (window.console && isDebugEnabled) { console.log("Debug Message"); }
上面的代码块必须在任何地方用于login,以便首先validation当前浏览器是否支持控制台,以及是否启用debugging。
isDebugEnabled
必须根据我们的环境设置为true或false。
我基本上覆盖了console.log函数,知道代码在哪里运行。 因此,我可以继续使用console.log,因为我总是这样做。 它会自动知道我在dev / qa模式下还是在生产中。 也有办法强制它。 这是一个工作小提琴。 http://jsfiddle.net/bsurela/Zneek/
这是堆栈溢出被发布jsfiddle的人暗示的片段
log:function(obj) { if(window.location.hostname === domainName) { if(window.myLogger.force === true) { window.myLogger.original.apply(this,arguments); } }else { window.myLogger.original.apply(this,arguments); } },
TL; DR
想法:logging对象排除了垃圾收集。
细节
- 如果您将对象传递给
console.log
那么可以通过DevTools的控制台引用来访问这些对象。 你可以通过logging对象来检查它,改变它,并发现旧的消息反映了对象的后来的变化。 - 如果日志过久,旧的邮件会在Chrome中被删除。
- 如果日志很短,则旧消息不会被删除,如果这些消息引用了对象,则这些对象不会被垃圾收集。
这只是一个想法:我检查了点1和2,但不是3。
解
如果您想为了客户端故障排除或其他需要而保留日志,请执行以下操作:
['log', 'warn', 'error'].forEach( (meth) => { const _meth = window.console[meth].bind(console); window.console[meth] = function(...args) { _meth(...args.map((arg) => '' + arg)) } });