Nodejs:获取调用函数的文件名

ein*_*ein 23 javascript node.js

我想知道如何获得函数调用者的绝对路径?

让我们说:

在文件中a.js我打电话b(); b()是文件中定义的函数b.js.a.js需要b.那么如何a.jsb.js节点中获取绝对路径?

小智 37

无法恢复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;
}
Run Code Online (Sandbox Code Playgroud)


小智 26

这是一个如何使用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;
}
Run Code Online (Sandbox Code Playgroud)

  • 重要的!向下滚动一点,有更新的答案,它们没有与此相同的潜在错误和陷阱(尽管我确实对其进行了编辑以省略最严重的错误)。@Christoph 的似乎是最好的。 (5认同)
  • 这应该是公认的答案:http://stackoverflow.com/a/29581862/11236 (2认同)

imm*_*mme 8

不完全回答这里的问题,但有些人可能会欣赏这些信息。

使用 NodeJS & Forever(-monitor),以下内容包含启动进程的文件名:

process.mainModule.filename
Run Code Online (Sandbox Code Playgroud)

虽然没有尝试过很多用途™。

这似乎是一个相当不错的解释:https : //code.google.com/p/v8/wiki/JavaScriptStackTraceApi


Chr*_*oph 7

如果您需要的调用程序文件的函数未在实现 \xe2\x80\x93 的文件中调用,就像 OP 场景 \xe2\x80\x93 中的情况一样,您可以编写:

\n
function _getCallerFile()\n{\n    const prepareStackTraceOrg = Error.prepareStackTrace;\n    const err = new Error();\n\n    Error.prepareStackTrace = (_, stack) => stack;\n\n    const stack = err.stack;\n\n    Error.prepareStackTrace = prepareStackTraceOrg;\n\n    return stack[1].getFileName();\n}\n
Run Code Online (Sandbox Code Playgroud)\n

try...catch不必要的,因为Error如果将其分配给变量,则不会抛出 。

\n

_getCallerFile此外,如果你想在多个项目中使用它,你可能想放入它自己的文件,但是这样,你将得到_getCallerFile被调用的文件的名称。\n在这种情况下,只需写入return stack[2].getFileName();,即再执行一步回到调用堆栈中。

\n

如果您使用 TypeScript,则必须编写,const stack = err.stack as unknown as NodeJS.CallSite[];因为Error.stack\ 的声明类型是string,但我们的prepareStackTrace函数返回一个对象数组NodeJS.CallSite

\n

仅供参考:NodeJS.CallSite还有更多有趣的方法,例如getFunctionName.

\n

更新

\n

Error.prepareStackTrace === undefined在分配 lambda 之前注意到了这一点。如果你不相信我,只需添加console.log(\'prepareStackTraceOrg:\', prepareStackTraceOrg);到该函数中即可。\n因此,我们可以简化该函数:

\n
function _getCallerFile()\n{\n    const err = new Error();\n\n    Error.prepareStackTrace = (_, stack) => stack;\n\n    const stack = err.stack;\n\n    Error.prepareStackTrace = undefined;\n\n    return stack[1].getFileName();\n}\n
Run Code Online (Sandbox Code Playgroud)\n