angularjs $log - 显示行号
Posted
技术标签:
【中文标题】angularjs $log - 显示行号【英文标题】:angularjs $log - show line number 【发布时间】:2014-01-11 09:16:54 【问题描述】:我在 chrome 中使用 angularjs $log,但它显示的行如下:angular.js:9037
。我想显示我调用此方法的行号。 (显示我的 js 名称和正确的行)。有谁知道该怎么做? Angular 没有这个功能。
【问题讨论】:
我不认为 $log 可以输出行号 有点不相关,但这个 chrome 插件有一些很棒的调试器工具:chrome.google.com/webstore/detail/angularjs-batarang/… 在 V8 javascript (Chrome & Node.js) 中访问行号:***.com/questions/11386492/… 见:***.com/questions/16300393/… 【参考方案1】:行号来自运行时。一般情况下不能设置。
但并非全部丢失。在行号非常重要的地方,您可以使用不同的呼叫。
记得注入$window
然后:
$window.console.log("test1");
您通过这种方式丢失了一些东西,例如格式化、跨浏览器填充代码等,但您确实可以免费获得正确的行号,而无需任何运行时特定的代码。
【讨论】:
【参考方案2】:您可以通过将装饰器应用于$log
服务来访问它:
module.config(function logConfig($provide, $logProvider)
$provide.decorator('$log', function ($delegate)
var originalFns = ;
// Store the original log functions
angular.forEach($delegate, function (originalFunction, functionName)
originalFns[functionName] = originalFunction;
);
var functionsToDecorate = ['debug', 'warn'];
// Apply the decorations
angular.forEach(functionsToDecorate, function (functionName)
$delegate[functionName] = logDecorator(originalFns[functionName]);
);
return $delegate;
);
function logDecorator(fn)
return function ()
var args = [].slice.call(arguments);
// Insert a separator between the existing log message(s) and what we're adding.
args.push(' - ');
// Use (instance of Error)'s stack to get the current line.
var stack = (new Error()).stack.split('\n').slice(1);
// Throw away the first item because it is the `$log.fn()` function,
// but we want the code that called `$log.fn()`.
stack.shift();
// We only want the top line, thanks.
stack = stack.slice(1, 2);
// Put it on the args stack.
args.push(stack);
// Call the original function with the new args.
fn.apply(fn, args);
;
);
我将此作为一个可包含的模块,但我相信它也可以在应用程序的 .config()
中完成。
我通过将许多不同的在线资源粘合在一起来构建这个(以及一些额外的逻辑);我通常非常擅长保留对它们的引用,但我想我在构建它时没有这样做,所以很遗憾我无法引用我的灵感。如果有人回复,我会放在这里。
注意 1: 这是我实际使用的稍微精简的版本,因此您必须仔细检查
logDecorator()
s 堆栈 出风头的魔法,虽然它应该像介绍的那样工作。注意 B: MDN says 认为
Error.prototype.stack
是非标准的(需要 IE10 并且可能在许多移动浏览器上不受支持),因此您可能需要考虑使用类似 stacktracejs 的东西来增强它以获取堆栈本身。
【讨论】:
【参考方案3】:在 Chrome 中有一个称为黑盒的功能。 您可以使用它从调试会话或开发工作流程中排除/绕过(库)源。
因此,如果您使用黑盒角度,$log 服务的内部将被绕过,控制台会打印正确的行号!
https://developer.chrome.com/devtools/docs/blackboxing
【讨论】:
天哪,太好了。 Firefox 显然也有黑盒,但它似乎不会影响控制台中的行号。也许是时候回去使用 Chrome了... 哇,非常好!我认为 chrome 文档有点过时了 - 运行 Chrome 版本 50.0.2661.94,您不能再右键单击源文件并将其黑盒化。我必须通过开发工具设置添加模式。 超级好的解决方案,它就像一个魅力,非常感谢! @Rob 我正在使用 Angular +2,我想创建自己的日志服务来打印调用者行号。可以应用这个解决方案吗?我可以黑盒我的服务吗?如何?【参考方案4】:接近floatingLomas's答案
module.config(function($logProvider, $provide)
$provide.decorator('$log', function ($delegate)
$delegate.info = function ()
var args = [].slice.call(arguments);
if (window.console && window.console.table)
console.trace(args[0], args[1]);
else
$delegate.log(null, args)
;
return $delegate;
);
)
通常第二个 @ 行是您需要的,在本例中为 90618
【讨论】:
【参考方案5】:我使用了 floatingLomas 解决方案并进行了一些调整,因为它在 FF 上不太适用,堆栈略有不同。而且像IE这样的phantomjs不支持Error.stack就炸了。 日志位置在 chrome 中是可点击的,但在 ff 中是不可点击的。
app.config(function logConfig($provide, $logProvider)
$provide.decorator('$log', function ($delegate)
var originalFns = ;
// Store the original log functions
angular.forEach($delegate, function (originalFunction, functionName)
originalFns[functionName] = originalFunction;
);
var functionsToDecorate = ['debug', 'warn'];
// Apply the decorations
angular.forEach(functionsToDecorate, function (functionName)
$delegate[functionName] = logDecorator(originalFns[functionName]);
);
return $delegate;
);
function logDecorator(fn)
return function ()
var args = [].slice.call(arguments);
// Insert a separator between the existing log message(s) and what we're adding.
args.push(' - ');
// Use (instance of Error)'s stack to get the current line.
var newErr = new Error();
// phantomjs does not support Error.stack and falls over so we will skip it
if (typeof newErr.stack !== 'undefined')
var stack = newErr.stack.split('\n').slice(1);
if (navigator.userAgent.indexOf("Chrome") > -1)
stack.shift();
stack = stack.slice(0, 1);
var stackInString = stack + '';
var splitStack;
if (navigator.userAgent.indexOf("Chrome") > -1)
splitStack = stackInString.split(" ");
else
splitStack = stackInString.split("@");
var lineLocation = splitStack[splitStack.length - 1];
// Put it on the args stack.
args.push(lineLocation);
// Call the original function with the new args.
fn.apply(fn, args);
;
【讨论】:
【参考方案6】:我结合了这个页面上的几个解决方案,以及其他解决方案,在 JSFiddle 中构建了一个简单的演示 - 演示 $log 服务的使用,使用装饰器对其进行增强以添加行号($log 调用所在的行号制成)。我还在 Plunker 中做了一个更全面的解决方案,演示了 $log 服务的使用,使用装饰器对其进行了增强,以添加行号、调用者文件名和实例名。希望这对其他人有用。
JSFiddle 网址 - https://jsfiddle.net/abhatia/6qnz0frh/
这个小提琴已经用以下浏览器测试过:
IE 11 - (JSFiddle Javascript 的第一行编号是 72)。 Firefox 46.0.1 -(JSFiddle Javascript 的第一行编号是 72)。 Chrome 50.0.2661.94 m -(JSFiddle Javscript 的第一行编号为 71)。结果很好。但是,请注意 Chrome 中的行号与 FF 或 IE 相比会减 1,即因为 JSFiddle 的 javascript 代码的第一行号在 FF/IE 和 Chrome 之间有所不同,如上所示。
Plunker URL - https://embed.plnkr.co/YcfJ7V/
这个plunk很好地展示了这个概念,有详细的解释,并且还提供了带有Angular官方默认$log服务示例的控制台输出,因此可以将两者进行对比。 Plunk 也已经在上面列出的浏览器上进行了测试。
下面的屏幕截图是上面 Plunk 示例的控制台输出。有 3 个突出显示的区域:
红框显示使用默认 $log 服务的控制台输出。从控制器调用的 $log 函数。 蓝色框显示使用扩展 $log 服务的控制台输出。从控制器调用的 $log 函数。您可以看到脚本名称和行号的显示方式,以及控制器名称(在实例化 $log 时使用)。 橙色框对比默认控制台输出和扩展 $log 服务。当您查看 Plunk 代码时,这一点会变得非常清楚。
这里是 JSFiddle 中使用的 getLineNumber 函数(略微增强的版本使用 Plunker 示例返回调用者文件名):
function getLineNumber(newErr, sliceIndex1, sliceIndex2)
var lineNumber = -1;
var lineLocation;
var stack = newErr.stack.split('\n').slice(2);
if (navigator.userAgent.indexOf("Chrome") > -1)
stack.shift();
stack = stack.slice(sliceIndex1, sliceIndex2);
var stackInString = stack + '';
var splitStack;
if (navigator.userAgent.indexOf("Chrome") > -1)
splitStack = stackInString.split(" ");
else
splitStack = stackInString.split("@");
lineLocation = splitStack[splitStack.length - 1];
//console.log(lineLocation);
lineNumber = lineLocation.split(":")[2];
return lineNumber;
【讨论】:
为我工作。有点讽刺的是,您正在使用 console.log 进行调试! :) 此外,我不确定在 Chrome 的 getLineNumber 中是否需要对 lineLocation 进行拆分。似乎 lineLocation 字符串是唯一需要的。【参考方案7】:我使用 chrome 版本 65.0.3325.181
就我而言,
进入菜单,设置 -> 黑盒 检查黑盒内容脚本 添加方块模式 angular.js
【讨论】:
以上是关于angularjs $log - 显示行号的主要内容,如果未能解决你的问题,请参考以下文章
log4j日志文件名与行号显示乱码? 问号? 参数问号? 日志问号?补