有没有比process.cwd()确定正在运行的node.js进程的根目录更好的方法?类似于Rails.root,但适用于Node.js。我正在寻找尽可能可预测和可靠的东西。
process.cwd()
Rails.root
有几种方法可以解决此问题,每种方法各有利弊:
从http://nodejs.org/api/modules.html:
直接从Node运行文件时,require.main将其设置为module。这意味着您可以通过测试确定文件是否已经直接运行require.main === module 因为module提供了一个filename属性(通常等效于__filename),所以可以通过检查获得当前应用程序的入口点require.main.filename。
直接从Node运行文件时,require.main将其设置为module。这意味着您可以通过测试确定文件是否已经直接运行require.main === module
require.main
module
require.main === module
因为module提供了一个filename属性(通常等效于__filename),所以可以通过检查获得当前应用程序的入口点require.main.filename。
filename
__filename
require.main.filename
因此,如果您想要应用程序的基本目录,则可以执行以下操作:
var path = require('path'); var appDir = path.dirname(require.main.filename);
这在大多数情况下都可以正常工作,但是如果您使用 pm2之 类的启动器运行应用程序或运行 mocha 测试,则此方法将失败。
节点有一个名为的全局命名空间对象global-您附加到此对象的任何对象都将在您的应用程序中的任何位置可用。因此,您可以在您index.js(或app.js您的主应用程序文件中使用任何名称)中定义一个全局变量:
global
index.js
app.js
// index.js var path = require('path'); global.appRoot = path.resolve(__dirname); // lib/moduleA/component1.js require(appRoot + '/lib/moduleB/component2.js');
可以始终如一地工作,但是您必须依赖全局变量,这意味着您无法轻松地重用组件/等。
这将返回当前工作目录。完全不可靠,因为它完全取决于进程 从 哪个目录启动:
$ cd /home/demo/ $ mkdir subdir $ echo "console.log(process.cwd());" > subdir/demo.js $ node subdir/demo.js /home/demo $ cd subdir $ node demo.js /home/demo/subdir
为了解决这个问题,我创建了一个名为 app-root-path 的节点模块。用法很简单:
var appRoot = require('app-root-path'); var myModule = require(appRoot + '/lib/my-module.js');
的 应用程序根路径 模块使用多种不同的技术来确定该应用程序的根路径,考虑到全球范围内安装的模块(例如,如果应用程序在运行/var/www/,但模块安装在~/.nvm/v0.x.x/lib/node/)。它不会100%地起作用,但是可以在大多数常见情况下起作用。
/var/www/
~/.nvm/v0.x.x/lib/node/
在大多数情况下无需配置即可工作。还提供了一些不错的附加便利方法(请参阅项目页面)。最大的缺点是,如果出现以下情况,它将不起作用:
node_modules
您可以通过设置APP_ROOT_PATH环境变量或调用.setPath()模块来解决此问题,但是在这种情况下,最好使用该global方法。
APP_ROOT_PATH
.setPath()
如果您正在寻找一种 确定 当前应用程序根路径的方法,则上述解决方案之一可能最适合您。另一方面,如果您要解决可靠加载应用程序模块的问题,则强烈建议您调查NODE_PATH环境变量。
NODE_PATH
Node的模块系统在各种位置查找模块。 这些位置之一是任何process.env.NODE_PATH位置。如果设置此环境变量,则可以require使用标准模块加载器进行模块更改,而无需进行其他任何更改。
process.env.NODE_PATH
require
例如,如果您将设置NODE_PATH为/var/www/lib,则以下内容将可以正常工作:
/var/www/lib
require('module2/component.js'); // ^ looks for /var/www/lib/module2/component.js
一个很好的方法是使用npm:
npm
"scripts": { "start": "NODE_PATH=. node app.js" }
现在,您可以使用来启动您的应用程序了npm start,这就是您的黄金。我将其与我的force-node- path模块结合使用,这可以防止意外加载未NODE_PATH设置的应用程序。有关对执行环境变量的更多控制,请参见checkenv。
npm start
一个陷阱: NODE_PATH 必须 在节点应用程序 外部 设置。您无法执行类似的操作,process.env.NODE_PATH = path.resolve(__dirname)因为模块加载程序会在应用运行之前缓存要搜索的目录列表。
process.env.NODE_PATH = path.resolve(__dirname)
[16年4月6日添加] 另一个试图解决此问题的非常有前途的模块是波浪形的。