我想知道如何获得函数调用者的绝对路径?
让我们这么说:
在a.js
我打电话的文件中b()
;b()
是文件中定义的函数b.js
。a.js
需要b
. 那么如何从节点中获取a.js
绝对路径?b.js
我想知道如何获得函数调用者的绝对路径?
让我们这么说:
在a.js
我打电话的文件中b()
;b()
是文件中定义的函数b.js
。a.js
需要b
. 那么如何从节点中获取a.js
绝对路径?b.js
无法恢复 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;
}
这是一个如何使用堆栈跟踪在节点中查找调用者文件的示例
function _getCallerFile() {
var filename;
var _pst = Error.prepareStackTrace
Error.prepareStackTrace = function (err, stack) { return stack; };
try {
var err = new Error();
var callerfile;
var currentfile;
currentfile = err.stack.shift().getFileName();
while (err.stack.length) {
callerfile = err.stack.shift().getFileName();
if(currentfile !== callerfile) {
filename = callerfile;
break;
}
}
} catch (err) {}
Error.prepareStackTrace = _pst;
return filename;
}
这里没有完全回答这个问题,但有些人可能会欣赏这些信息。
使用 NodeJS 和 Forever(-monitor),以下内容包含启动进程的文件名:
process.mainModule.filename
虽然没有尝试过很多用途™。
这似乎是一个相当不错的解释:https ://code.google.com/p/v8/wiki/JavaScriptStackTraceApi 。
使用https://github.com/sindresorhus/callsites
如果您使用第一个答案,您可能会弄乱其他试图做同样事情的库。参见例如:https ://github.com/facebook/jest/issues/5303
如果你需要的调用者文件没有在实现它的文件中调用——就像在 OP 的场景中一样——你可以写:
function _getCallerFile()
{
const prepareStackTraceOrg = Error.prepareStackTrace;
const err = new Error();
Error.prepareStackTrace = (_, stack) => stack;
const stack = err.stack;
Error.prepareStackTrace = prepareStackTraceOrg;
return stack[1].getFileName();
}
try...catch
是不必要的,因为如果Error
将其分配给变量,则不会抛出。
此外,如果您想在多个项目中使用它,您可能需要放入_getCallerFile
它自己的文件,但是,您将获得_getCallerFile
被调用的文件的名称。在这种情况下,只需编写return stack[2].getFileName();
,即在调用堆栈中再退一步。
如果你使用 TypeScript,你必须写const stack = err.stack as unknown as NodeJS.CallSite[];
,因为Error.stack
的声明类型是string
,但是我们的prepareStackTrace
函数返回一个对象数组NodeJS.CallSite
。
仅供参考:NodeJS.CallSite
还有更多有趣的方法,例如getFunctionName
.
更新
我注意到Error.prepareStackTrace === undefined
在分配 lambda 之前。如果您不信任我,请添加console.log('prepareStackTraceOrg:', prepareStackTraceOrg);
到该功能。因此,我们可以简化函数:
function _getCallerFile()
{
const err = new Error();
Error.prepareStackTrace = (_, stack) => stack;
const stack = err.stack;
Error.prepareStackTrace = undefined;
return stack[1].getFileName();
}
npm caller 包有一个函数可以返回调用者的路径和文件名。
在 JavaScript 中获取堆栈跟踪非常困难。我发现最好的方法是抛出一个错误,捕获它,从中获取堆栈Error.getStack()
(不是在所有浏览器中实现,这意味着你是 IE。)并格式化输出。
每个堆栈帧都会为您提供文件路径、行号和函数名称。Webkit 甚至支持参数,但是当我上次检查时它还没有工作。
然后是跨不同事件跟踪代码的问题。
我实际上写了一篇关于此的博客文章:http: //fritsvancampen.wordpress.com/2013/03/28/error-handling-in-javascript-a-better-way/
您可以使用require.resolve(module)
来确定模块的完整路径:
var path = require.resolve("a");
//or
var path = require.resolve("./a.js");