目前,我的代码中到处都有这个JS语句:
window.console && console.log("Foo");
我想知道这是否昂贵,或在生产中有任何负面影响。
我可以随意离开客户端登录,还是应该退出?
编辑:最后,我想我(以及其他任何人?)可以提出的最佳论据是,通过保留日志消息,在服务器和客户端之间传输的额外数据的数量可能微不足道。要完全优化生产代码,必须删除日志记录,以减少发送给客户端的javascript的大小。
Answers:
你应该不开发工具添加到生产页面。
要回答另一个问题:代码不能产生负面影响:
window.console
如果console
未定义,将评估为falseconsole.log("Foo")
将在定义消息后将消息打印到控制台(前提是该页面不会console.log
被非功能覆盖)。/*DEBUG:start*/console.log("Foo");/*DEBUG:end*/
。然后,使用RegExp删除所有出现的/*DENUG-start*/[\S\s]*?/*DEBUG-end*/
。其余的空白字符将被最小化器删除。
处理此问题的另一种方法是在未定义控制台对象时“存根”,因此在没有控制台的上下文中不会引发任何错误,即
if (!window.console) {
var noOp = function(){}; // no-op function
console = {
log: noOp,
warn: noOp,
error: noOp
}
}
您知道了...在控制台的各种实现上定义了很多功能,因此您可以将它们全部或仅使用的功能存根(例如,如果您仅使用过console.log
而从未使用过console.profile
,console.time
等等...)
对我来说,这比在每个调用之前添加条件或不使用条件更好。
$.noop
。
如果您使用的是这个缩小器,则可以设置drop_console
option:
传递true以放弃对console。*函数的调用
因此,我建议保留 console.log
呼叫,因为它们是代码库中最棘手的部分。
drop_console
为false
,观察它们并再次隐藏它们。
如果缩小是构建过程的一部分,则可以使用它来去除调试代码,如Google封闭编译器在此处所述:在缩小过程中排除调试JavaScript代码
if (DEBUG) {
console.log("Won't be logged if compiled with --define='DEBUG=false'")
}
如果使用高级优化进行编译,则该代码甚至会被识别为无效代码并被完全删除
是。在不支持console.log的浏览器中,console.log将引发异常(将找不到控制台对象)。
通常是的,在生产代码中公开日志消息不是一个好主意。
理想情况下,在部署之前,应使用构建脚本删除此类日志消息。但许多(大多数)人(包括我)不使用构建过程。
这是我最近一直在使用的一些代码的简短摘要,以解决这一难题。它修复了由console
旧IE中未定义引起的错误,以及在“ 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);
}
我很确定我addConsoleNoOp
从SO的另一个答案中提取了上述f'n的大部分内容,但现在无法找到。如果找到,我将在以后添加参考。
编辑:不是我在想的帖子,但是这是一种类似的方法: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
用于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");
}
上面的代码块必须在所有地方都用于日志记录,以便首先验证当前浏览器是否支持该控制台以及是否启用了调试。
isDebugEnabled
必须根据我们的环境设置为true或false。
想法:记录对象可以防止它们被垃圾收集。
console.log
对象,则可以通过DevTools控制台的引用来访问这些对象。您可以通过记录对象,对其进行变异并发现旧消息反映该对象的以后更改来进行检查。这只是一个主意:我检查了第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)) }
});
我基本上用一个知道代码在哪里运行的函数来覆盖console.log函数。因此,我可以像往常一样继续使用console.log。它会自动知道我处于开发/质量保证模式或生产环境。还有一种强制的方法。这是一个工作的小提琴。 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);
}
},
我知道这是一个很老的问题,而且一段时间以来没有进行太多活动。我只想添加自己想出的解决方案,这对我来说似乎很好。
/**
* 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;
}
}
}
然后,通常我会在这样的脚本中创建一个函数,或者可以在全局脚本中使它可用:
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!');
}
}
}
然后我只用它而不是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);
}
如果使用正确的工具(例如parcel
/ )完成了工作流程,webpack
那么不再麻烦,因为production
构建console.log
已被删除。甚至几年前与Gulp
/Grunt
它可能已经自动为好。
许多现代的框架如Angular
,React
,Svelte
,Vue.js
来与设置外的开箱。基本上,只要部署正确的构建(即production
一个development
仍不存在的构建),您就无需执行任何操作console.log
。