除了process.cwd()之外,是否有其他方法来获取当前项目根目录的路径名。Node是否实现了ruby的属性Rails.root之类的东西。我要找的是稳定可靠的东西。


当前回答

只使用:

 path.resolve("./") ... output is your project root directory

其他回答

在使用express时,我发现一个有用的技巧是在设置任何其他路由之前将以下内容添加到app.js中

// set rootPath
app.use(function(req, res, next) {
  req.rootPath = __dirname;
  next();
});

app.use('/myroute', myRoute);

不需要使用全局变量,您可以将根目录的路径作为请求对象的属性。

如果你的app.js在你的项目的根目录中,这是有效的,默认情况下,它是。

__dirname会给你根目录,只要你在根目录下的文件中。

// ProjectDirectory.js (this file is in the project's root directory because you are putting it there).
module.exports = {

    root() {
        return __dirname;
    }
}

在其他文件中:

const ProjectDirectory = require('path/to/ProjectDirectory');
console.log(`Project root directory is ${ProjectDirectory.root}`);

__dirname不是全局变量;它是当前模块的局部值,因此每个文件都有自己的局部值,不同的值。

如果您想要运行进程的根目录,则可能需要使用process.cwd()。

如果希望获得可预测性和可靠性,那么可能需要将设置某个环境变量作为应用程序的要求。你的应用程序寻找MY_APP_HOME(或任何东西),如果它在那里,应用程序存在于该目录,那么一切都很好。如果它是未定义的,或者目录不包含您的应用程序,那么它应该退出,并提示用户创建变量。可以将其设置为安装过程的一部分。

您可以使用process.env.MY_ENV_VARIABLE来读取节点中的环境变量。

就像在根目录中添加这一行到你的模块一样简单,通常是app.js或app.ts。

global.__basedir = __dirname;

然后所有模块都可以访问_basedir。

注意:对于typescript实现,遵循上面的步骤,然后你将能够使用global.__basedir使用根目录路径

这将沿着目录树向下走,直到它包含一个node_modules目录,通常表示你的项目根目录:

const fs = require('fs')
const path = require('path')

function getProjectRoot(currentDir = __dirname.split(path.sep)) {
  if (!currentDir.length) {
    throw Error('Could not find project root.')
  }
  const nodeModulesPath = currentDir.concat(['node_modules']).join(path.sep)
  if (fs.existsSync(nodeModulesPath) && !currentDir.includes('node_modules')) {
    return currentDir.join(path.sep)
  }
  return this.getProjectRoot(currentDir.slice(0, -1))
}

它还确保返回路径中没有node_modules,因为这意味着它包含在嵌套包安装中。