当前位置: 首页 > 面试题库 >

从运行的node.js应用程序确定项目根目录

南宫俊喆
2023-03-14
问题内容

有没有比process.cwd()确定正在运行的node.js进程的根目录更好的方法?类似于Rails.root,但适用于Node.js。我正在寻找尽可能可预测和可靠的东西。


问题答案:

有几种方法可以解决此问题,每种方法各有利弊:

require.main.filename

从http://nodejs.org/api/modules.html:

直接从Node运行文件时,require.main将其设置为module。这意味着您可以通过测试确定文件是否已经直接运行require.main === module

因为module提供了一个filename属性(通常等效于__filename),所以可以通过检查获得当前应用程序的入口点require.main.filename

因此,如果您想要应用程序的基本目录,则可以执行以下操作:

var path = require('path');
var appDir = path.dirname(require.main.filename);

优点缺点

这在大多数情况下都可以正常工作,但是如果您使用 pm2之 类的启动器运行应用程序或运行 mocha 测试,则此方法将失败。

全局X

节点有一个名为的全局命名空间对象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');

优点缺点

可以始终如一地工作,但是您必须依赖全局变量,这意味着您无法轻松地重用组件/等。

process.cwd()

这将返回当前工作目录。完全不可靠,因为它完全取决于进程 哪个目录启动:

$ 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%地起作用,但是可以在大多数常见情况下起作用。

优点缺点

在大多数情况下无需配置即可工作。还提供了一些不错的附加便利方法(请参阅项目页面)。最大的缺点是,如果出现以下情况,它将不起作用:

  • 您正在使用启动器,例如pm2
  • AND ,该模块未安装在您应用的node_modules目录中(例如,如果您是全局安装的)

您可以通过设置APP_ROOT_PATH环境变量或调用.setPath()模块来解决此问题,但是在这种情况下,最好使用该global方法。

NODE_PATH环境变量

如果您正在寻找一种 确定
当前应用程序根路径的方法,则上述解决方案之一可能最适合您。另一方面,如果您要解决可靠加载应用程序模块的问题,则强烈建议您调查NODE_PATH环境变量。

Node的模块系统在各种位置查找模块。
这些位置之一是任何process.env.NODE_PATH位置。如果设置此环境变量,则可以require使用标准模块加载器进行模块更改,而无需进行其他任何更改。

例如,如果您将设置NODE_PATH/var/www/lib,则以下内容将可以正常工作:

require('module2/component.js');
// ^ looks for /var/www/lib/module2/component.js

一个很好的方法是使用npm

"scripts": {
    "start": "NODE_PATH=. node app.js"
}

现在,您可以使用来启动您的应用程序了npm start,这就是您的黄金。我将其与我的force-node-
path模块结合使用,这可以防止意外加载未NODE_PATH设置的应用程序。有关对执行环境变量的更多控制,请参见checkenv。

一个陷阱: NODE_PATH 必须 在节点应用程序 外部
设置。您无法执行类似的操作,process.env.NODE_PATH = path.resolve(__dirname)因为模块加载程序会在应用运行之前缓存要搜索的目录列表。

[16年4月6日添加] 另一个试图解决此问题的非常有前途的模块是波浪形的。



 类似资料:
  • 我面临以下问题。我有一个多模块的Gradle项目。一个模块是我的根项目,第二个模块是集成测试。 为了让我的集成测试运行,复制任务需要首先运行,以便将一些资产移动到项目根目录上的文件夹中。 我已经在我的根项目上定义了这样一个任务,当我试图调用它时,它什么也不做(我尝试了几种不同的调用方式)。 由于失败,我继续在子项目本身上创建了以下任务: 这是我的另一个任务。我的目标是让它将根项目类以及在下生成的j

  • 我正在开始一门Android Studio课程,但我在运行代码时遇到了问题:事实上,当我使用Nexus S API 22点击“Run app”时,启动的是我的旧项目,而不是我的新项目。我有Android Studio 3.5 我试图重启Android Studio并启动全新的项目,但没有成功。 谢谢你的帮助。

  • 问题内容: 我有一个在AWS EC2的Linux上运行的Node.JS应用程序,该应用程序使用fs模块读取HTML模板文件。这是应用程序的当前结构: HTML模板将始终位于该位置,但是,模板读取服务可能会移动到其他位置(更深的子目录等)。在模板读取服务中,我使用fs.readFileSync()加载文件,就像这样: 这将引发以下错误: 我假设这是因为路径“ ./”解析为“ / services /

  • 几天以来我一直有这个问题。 我启动Android Studio和GenyMotion,打开一个项目,运行应用程序,一切正常。 接下来,我通过做一些更改来编辑我的项目,保存文件,然后再次运行它,但它不会运行我的最新更改,而是运行之前的旧更改,而没有更改。(在我编辑我的项目之前) 为了纠正这一点并使其从最新的代码运行,我关闭了Studio和Genymotion,然后重新开始。但是,整个循环再次重复。

  • 问题内容: 我正在尝试将上载的多部分文件写入文件系统。我有一个名为audio的目录,该目录位于Web应用程序的根目录中(不在WEB- INF内,但在它旁边,可以像CSS和javascript一样公开访问)。 我想将上传的文件写入该目录,但似乎无法获取所需的路径。我以为使用ServletPath()然后使用realPath()可能可行,但是我没有通过Spring控制器对ServletContext的

  • 如何使用多个使用相同库的应用程序创建gradle根项目。我希望以包含以下内容的tar和zip文件结束: 导致错误