Nodejs方法执行者文件路径相关问题

Nodejs方法执行者文件路径相关问题

**a.js 在目录 /home/test/a.js **

var b = require("../lib/b.js");
b.test();

b.js 在目录 /home/lib/b.js

export.test = function(){
// 在这里我需要知道a.js的路径,怎么解决?
//  尝试过 new Error() 里面解析栈信息 可是得到的是 module.js 并不能够得到此方法调用者  a.js 的真实路径
}

现在我只能在 a.js 中取得 __dirname 作为参数传递到b.js 有没有不传参直接获取的方法呢?


7 回复

在 Node.js 中,如果你需要在 b.js 文件中获取调用它的 a.js 的文件路径,通常的做法是通过参数传递。不过,你也可以利用一些技巧来动态获取调用者的路径。以下是一个示例,展示如何实现这一点。

示例代码

a.js

var b = require("./lib/b");

console.log("a.js directory:", __dirname);

b.test();

b.js

function getCallerFile() {
    try {
        throw new Error();
    } catch (e) {
        if (!e.stack) return null;
        
        // 解析堆栈信息以获取调用者的文件路径
        var stackLines = e.stack.split('\n');
        var callerLine = stackLines[3]; // 调用者的堆栈信息在第三行(具体位置可能因环境而异)
        var matches = callerLine.match(/at\s+(.*)/);
        if (matches && matches[1]) {
            return matches[1].trim();
        }
    }
    return null;
}

exports.test = function() {
    var callerFilePath = getCallerFile();
    console.log("Caller file path:", callerFilePath);
};

解释

  1. 抛出错误并捕获堆栈信息

    • b.js 中,我们通过 throw new Error() 来生成一个错误对象,并捕获它。
    • 错误对象包含堆栈信息,这些信息可以帮助我们找到调用者的位置。
  2. 解析堆栈信息

    • 我们使用 e.stack.split('\n') 将堆栈信息分割成多行。
    • 第三行通常是调用者的堆栈信息(具体位置可能因环境而异)。
    • 使用正则表达式 matches(/at\s+(.*)/) 来提取调用者的文件路径。
  3. 获取调用者的文件路径

    • 通过上述方法,我们可以从堆栈信息中提取出调用者的文件路径。

这种方法虽然可以获取调用者的文件路径,但需要注意的是,它依赖于 Node.js 的堆栈跟踪机制,并且可能会因为不同的运行环境而有所不同。因此,在实际项目中,建议优先考虑通过参数传递路径信息,以确保代码的可维护性和可靠性。


为什么你不想用参数传递的方法?

b.js: exports.test = function() { console.log(module.parent.filename); }; 不过我觉得这样不太好把。。

往global里放一个项目根目录,然后约定之下的子目录结构~~

其实还是传参方式比较好。。

艹,能不能不要这样耦合淫家……

传参好

在Node.js中,如果你想在b.js中获取a.js的路径,而不通过参数传递,可以通过追踪调用堆栈来实现。虽然这种方式不如直接传递参数直观,但确实可以达到目的。

示例代码

a.js

var b = require("./lib/b.js");  // 注意这里的相对路径
b.test();

b.js

function getCallerFile() {
    try {
        throw new Error();
    } catch (e) {
        var lines = e.stack.split('\n');
        // 跳过前两行,因为它们通常包含错误信息和throw语句
        for (let i = 2; i < lines.length; i++) {
            let match = lines[i].match(/at\s+(?:<anonymous>|(\w[\w.]*))\s+\((.*):(\d*):(\d*)\)/);
            if (match && !match[1]) {  // 确保不是模块内部调用
                return match[2];
            }
        }
    }
    return null;
}

module.exports = {
    test: function () {
        const callerFilePath = getCallerFile();
        console.log('Caller file path:', callerFilePath);
    }
};

解释

  1. getCallerFile 函数:

    • 抛出一个错误并捕获它。
    • 通过Error对象的stack属性,我们可以获取到调用堆栈的信息。
    • 我们遍历堆栈信息,查找包含文件路径的那一行,并返回该文件路径。
  2. test 方法:

    • test 方法调用了 getCallerFile 函数,该函数会返回调用它的文件路径(即 a.js 的路径)。

这种方法虽然能够解决问题,但是请注意,依赖于错误堆栈信息的方式可能不够健壮,特别是在不同的JavaScript引擎或环境中可能表现不同。因此,在实际开发中,更推荐直接通过参数传递所需的信息。

回到顶部