我想知道如何获得函数调用者的绝对路径?
让我们说:
在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
被调用的文件的名称。在这种情况下,只需 write 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();
}