我目前在我的代码中随处都有这个JS语句:
window.console && console.log("Foo");
我想知道这是否会带来高昂的代价,在生产环境中是否有任何负面影响。
我是否可以继续留下客户端日志记录,还是应该删除?
编辑:最终,我认为我(以及其他人)能提出的最好论据是,留下日志记录可能会在服务器和客户端之间传输非常大量的额外数据。如果要完全优化生产代码,则需要删除日志记录以减少发送到客户端的 JavaScript 大小。
我目前在我的代码中随处都有这个JS语句:
window.console && console.log("Foo");
我想知道这是否会带来高昂的代价,在生产环境中是否有任何负面影响。
我是否可以继续留下客户端日志记录,还是应该删除?
编辑:最终,我认为我(以及其他人)能提出的最好论据是,留下日志记录可能会在服务器和客户端之间传输非常大量的额外数据。如果要完全优化生产代码,则需要删除日志记录以减少发送到客户端的 JavaScript 大小。
另一种处理这个问题的方法是在控制台对象未定义时将其“存根化”,以便在没有控制台的上下文中不会抛出错误,即:
if (!window.console) {
var noOp = function(){}; // no-op function
console = {
log: noOp,
warn: noOp,
error: noOp
}
}
你可以想象一下...在各种控制台实现中定义了许多函数,因此您可以将它们全部存根化或仅存根化您使用的函数(例如,如果您只使用 console.log
而从未使用过 console.profile
、console.time
等)。
对我来说,这比在每个调用前添加条件或不使用它们更好。
$.noop
。 - crush您不应该将开发工具添加到生产页面中。
回答另一个问题:代码不能有负面影响:
window.console
如果未定义console
,则为falseconsole.log(“Foo”)
将在定义时打印消息到控制台(前提是页面没有使用非函数覆盖 console.log
)。/*DEBUG:start*/console.log("Foo");/*DEBUG:end*/
。然后,使用正则表达式删除所有出现的 /*DENUG-start*/[\S\s]*?/*DEBUG-end*/
。最后,剩下的空白字符将会被压缩工具删除。 - Rob W如果您正在使用这个压缩器,您可以设置 drop_console
选项:
将其设为true以丢弃对console.* 函数的调用
因此,我建议保留代码库中最繁琐的部分的 console.log
调用。
drop_console
设置为 false
,观察它们,然后再次隐藏它们。 - terales如果缩小文件大小(minification)是你构建过程的一部分,你可以使用它来删除调试代码,如Google闭包编译器在这里所解释的: Exclude debug JavaScript code during minification
if (DEBUG) {
console.log("Won't be logged if compiled with --define='DEBUG=false'")
}
window.console.log = () => {};
完成 ;) 这个monkey patches window.console 并用一个空函数替换 log 函数,禁用输出。
在大多数情况下,这对我来说已经足够好了。如果你想要“彻底”地从代码中删除console.logs以减小包的大小,你需要改变你的js打包方式(例如使用压缩工具丢弃console.logs)
此外,我认为你实际上可以为将它们保留在生产环境中提出有力的观点。对于普通用户来说,这不会改变任何事情,但确实可以加快理解奇怪的“异国浏览器”问题的速度。这不像后端日志可能包含关键信息。通过console.log显示的一切显然已经在前端可用!因此,不显示日志消息仅仅是因为你害怕透露安全细节之类的东西,这只是“安全性靠不透明性”的表现,应该让你思考为什么这些信息在前端首次可用!这只是我的意见。
一般而言,在生产代码中暴露日志消息并不是一个好主意。
理想情况下,您应该在部署之前使用构建脚本删除此类日志消息;但许多人(包括我)并不使用构建过程。
以下是我最近使用的一小段代码片段,用于解决这个问题。它修复了旧版IE中未定义的console
引起的错误,并在“开发模式”下禁用日志记录。
// 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 网站上的另一个答案,但现在找不到了。如果我找到,稍后会添加一个参考链接。
编辑:这不是我想到的帖子,但以下是类似的方法: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。
parcel
/webpack
,那么工作流就不再是头疼的问题了,因为在production
构建中,console.log
会被删除。即使在几年前使用Gulp
/Grunt
也可以自动化处理。
许多现代框架,如Angular
、React
、Svelte
和Vue.js
都默认提供了这样的设置。基本上,只要部署正确的构建,即production
构建,而不是仍然有console.log
的development
构建,你就无需进行任何操作。