Javascript Nodejs:获取调用方函数的文件名
我想知道如何获得函数调用方的绝对路径 可以这样说:Javascript Nodejs:获取调用方函数的文件名,javascript,node.js,Javascript,Node.js,我想知道如何获得函数调用方的绝对路径 可以这样说: 在文件a.js中,我调用b()b()是在文件b.js中定义的函数a.js需要b。那么如何从节点中的b.js获取a.js绝对路径呢?在JavaScript中获取堆栈跟踪非常困难。我发现的最好的方法是抛出一个错误,捕捉它,从Error.getStack()(并非在所有浏览器中都实现,这意味着您需要IE)获取堆栈并格式化输出 每个堆栈帧为您提供一个文件路径、行号和函数名。Webkit甚至支持参数,但我上次检查时,它还不起作用 然后是跨不同事件跟踪代码
在文件
a.js
中,我调用b()b()
是在文件b.js
中定义的函数a.js
需要b
。那么如何从节点中的b.js
获取a.js
绝对路径呢?在JavaScript中获取堆栈跟踪非常困难。我发现的最好的方法是抛出一个错误,捕捉它,从Error.getStack()
(并非在所有浏览器中都实现,这意味着您需要IE)获取堆栈并格式化输出
每个堆栈帧为您提供一个文件路径、行号和函数名。Webkit甚至支持参数,但我上次检查时,它还不起作用
然后是跨不同事件跟踪代码的问题
实际上,我写了一篇关于此的博文:您可以使用require.resolve(module)
来确定模块的完整路径:
var path = require.resolve("a");
//or
var path = require.resolve("./a.js");
这是一个如何使用stacktrace在节点中查找调用方文件的示例
function _getCallerFile() {
try {
var err = new Error();
var callerfile;
var currentfile;
Error.prepareStackTrace = function (err, stack) { return stack; };
currentfile = err.stack.shift().getFileName();
while (err.stack.length) {
callerfile = err.stack.shift().getFileName();
if(currentfile !== callerfile) return callerfile;
}
} catch (err) {}
return undefined;
}
这里不完全回答这个问题
但有些人可能会感激这些信息
使用NodeJS&Forever(-monitor),
以下文件包含启动进程的文件名:
process.mainModule.filename
没有尝试过很多用途™ 不过
这似乎是一个相当不错的解释:。无法恢复prepareStackTrace函数可能会导致问题。下面是一个消除副作用的示例
function _getCallerFile() {
var originalFunc = Error.prepareStackTrace;
var callerfile;
try {
var err = new Error();
var currentfile;
Error.prepareStackTrace = function (err, stack) { return stack; };
currentfile = err.stack.shift().getFileName();
while (err.stack.length) {
callerfile = err.stack.shift().getFileName();
if(currentfile !== callerfile) break;
}
} catch (e) {}
Error.prepareStackTrace = originalFunc;
return callerfile;
}
npm有一个返回调用者路径和文件名的函数。使用
如果你使用第一个答案,你可能会和其他试图做同样事情的图书馆搞砸。例如,请参见:如果在实现调用方文件的文件中没有调用所需的函数,则可以编写:
函数_getCallerFile()
{
const prepareStackTraceOrg=Error.prepareStackTrace;
const err=新错误();
Error.prepareStackTrace=(\uuz,堆栈)=>stack;
常量堆栈=err.stack;
Error.prepareStackTrace=prepareStackTraceOrg;
返回堆栈[1]。getFileName();
}
try…catch
是不必要的,因为如果将错误
赋给变量,则不会抛出该错误
此外,如果要在多个项目中使用\u getCallerFile
,您可能希望将其放入自己的文件中,但随后,您将获得调用\u getCallerFile
的文件的名称。
在这种情况下,只需编写返回堆栈[2].getFileName()代码>,i。E在调用堆栈中再后退一步
如果您使用的是TypeScript,则必须将const stack=err.stack写为NodeJS.CallSite[]未知因为Error.stack
声明的类型是string
,但是我们的prepareStackTrace
函数返回一个NodeJS.CallSite
对象数组
仅供参考:NodeJS.CallSite
还有更多有趣的方法,例如。g<代码>获取函数名
更新
在分配lambda之前,我注意到Error.prepareStackTrace===undefined
。如果您不信任我,只需添加console.log('prepareStackTraceOrg:',prepareStackTraceOrg)代码>到函数。
因此,我们可以简化函数:
函数_getCallerFile()
{
const err=新错误();
Error.prepareStackTrace=(\uuz,堆栈)=>stack;
常量堆栈=err.stack;
Error.prepareStackTrace=未定义;
返回堆栈[1]。getFileName();
}
try{throw new Error();}catch(e){console.log(JSON.stringify(e));}在NodeJSY上不起作用您无法对本机对象进行JSON编码。你为什么要这么做请看我的答案。肯定没有回答这个问题,但这对我有帮助。谢谢伟大的我花了几个小时试图解决一个与此相关的问题。重新分配原始函数修复了所有问题。您好,此解决方案运行良好。。。但是,如果在回调中调用了函数,那么它将获得触发回调的文件的名称。调用方并不总是预先确定的,因此:这种方式将不适用于合并路径或遍历路径。查找调用者的补丁是不同的。调用者包在调试时返回internal/module.js。github上发布的示例也返回与节点v8.11.1上调用者相同的“internal/module.js”。这是一个很好的答案。