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

时间:2013-05-22 17:11:30

标签: javascript node.js

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

我们说:

文件a.js中的

我致电b(); b()是文件b.js中定义的函数。 a.js需要b。那么如何从节点中的a.js获得b.js绝对路径?

8 个答案:

答案 0 :(得分:32)

无法恢复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;
}

答案 1 :(得分:25)

这是一个如何使用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;
}

答案 2 :(得分:4)

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

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

process.mainModule.filename

虽然没有尝试过多次使用。

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

答案 3 :(得分:1)

在JavaScript中获取堆栈跟踪非常困难。我找到的最好的方法是抛出一个错误,捕获它,从Error.getStack()获取堆栈(未在所有浏览器中实现,这意味着你的IE。)并格式化输出。

每个堆栈帧都为您提供文件路径,行号和函数名称。 Webkit甚至支持参数,但是当我上次检查时,它还没有工作。

然后存在跨不同事件跟踪代码的问题。

我实际上写了一篇关于此的博文:http://fritsvancampen.wordpress.com/2013/03/28/error-handling-in-javascript-a-better-way/

答案 4 :(得分:1)

您可以使用require.resolve(module)来确定模块的完整路径:

var path = require.resolve("a");

//or

var path = require.resolve("./a.js");

答案 5 :(得分:1)

npm caller package有一个函数可以返回调用者的路径和文件名。

答案 6 :(得分:1)

如果您需要调用者文件的函数没有在实现它的文件中被调用——就像在 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();,i。 e.在调用堆栈中再退一步。

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

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

更新

我在分配 lambda 之前注意到了 getFunctionName。如果您不相信我,只需在函数中添加 Error.prepareStackTrace === undefined。 因此,我们可以简化函数:

console.log('prepareStackTraceOrg:', prepareStackTraceOrg);

答案 7 :(得分:0)

使用https://github.com/sindresorhus/callsites

如果您使用第一个答案,则可能会与尝试执行相同操作的其他库混淆。例如,请参见:https://github.com/facebook/jest/issues/5303