Node.js包中如何动态获取调用方项目的根目录
解决方案
你原来直接传入'file.yaml'的写法依赖相对路径,Node.js的fs模块读取文件时,相对路径是相对于进程启动时的工作目录,不是代码文件所在目录,也不是调用方的目录,所以会出现找不到文件的问题,可通过以下几种方案实现动态获取调用方根目录:
方法1:基于入口文件路径推导(绝大多数场景适用)
Node.js中require.main指向启动时直接执行的入口模块(也就是本案例中的project/main.js),通过它可以固定拿到入口文件的绝对路径,推导得到项目根目录,不受进程启动位置影响:
修改module/index.js代码如下:
const fs = require('fs'); const path = require('path'); exports.test = function() { // 获取入口文件所在的目录,即为调用方应用的根目录 const appRoot = path.dirname(require.main.filename); const targetPath = path.join(appRoot, 'file.yaml'); console.log(fs.readFileSync(targetPath, 'utf8')); }
方法2:调用栈动态获取(适合多调用方场景)
如果你的模块可能被不同目录下的文件调用,需要匹配直接调用test方法的文件所在目录,可以通过解析Error的调用栈信息动态获取:
修改module/index.js代码如下:
const fs = require('fs'); const path = require('path'); // 获取调用方所在目录的工具函数 function getCallerDir() { const originalPrepare = Error.prepareStackTrace; Error.prepareStackTrace = (_, stack) => stack; const stack = new Error().stack.slice(1); Error.prepareStackTrace = originalPrepare; // 取第二层调用帧,即为test方法的调用方 const callerFilePath = stack[1].getFileName(); return path.dirname(callerFilePath); } exports.test = function() { const callerRoot = getCallerDir(); const targetPath = path.join(callerRoot, 'file.yaml'); console.log(fs.readFileSync(targetPath, 'utf8')); }
轻量方案(仅适合固定在根目录启动的场景)
如果你可以保证Node进程始终在项目根目录下启动,也可以直接用process.cwd()拼接路径,写法更简单:
const targetPath = path.join(process.cwd(), 'file.yaml');
注意:如果在非项目根目录下执行启动命令(比如在上级目录执行
node project/main.js),process.cwd()会返回执行命令的目录,会导致读取失败,生产环境更推荐前两种稳定方案。
内容的提问来源于stack exchange,提问作者MystPi
相关产品推荐
相关产品推荐

