gpt4 book ai didi

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

转载 作者:IT老高 更新时间:2023-10-28 21:44:52 24 4
gpt4 key购买 nike

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

最佳答案

有很多方法可以解决这个问题,每种方法都有自己的优点和缺点:require.main.filename来自 http://nodejs.org/api/modules.html :

When a file is run directly from Node, require.main is set to its module. That means that you can determine whether a file has been run directly by testing require.main === module

Because module provides a filename property (normally equivalent to __filename), the entry point of the current application can be obtained by checking require.main.filename.


因此,如果您想要应用程序的基本目录,您可以执行以下操作:
const { dirname } = require('path');
const appDir = dirname(require.main.filename);
优点缺点
这在大多数情况下都会很好用,但是如果您使用像 这样的启动器运行您的应用程序pm2 或运行 摩卡测试,此方法将失败。 module.pathsNode 将所有模块搜索路径发布到 module.paths .我们可以遍历这些并选择第一个解决的。
async function getAppPath() {
const { dirname } = require('path');
const { constants, promises: { access } } = require('fs');

for (let path of module.paths) {
try {
await access(path, constants.F_OK);
return dirname(path);
} catch (e) {
// Just move on to next path
}
}
}
优点缺点
这有时会起作用,但在包中使用时不可靠,因为它可能返回安装包的目录而不是安装应用程序的目录。
使用全局变量
Node 有一个名为 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
应用程序根路径
为了解决这个问题,我创建了一个名为 的 Node 模块。 app-root-path .用法很简单:
const appRoot = require('app-root-path');
const myModule = require(`${ appRoot }/lib/my-module.js`);
app-root-path 模块使用多种技术来确定应用程序的根路径,同时考虑到全局安装的模块(例如,如果您的应用程序在 /var/www/ 中运行,但模块安装在 ~/.nvm/v0.x.x/lib/node/ 中)。它不会在 100% 的情况下工作,但它会在大多数常见情况下工作。
优点缺点
大多数情况下无需配置即可工作。还提供了一些不错的附加便利方法(参见项目页面)。最大的缺点是它在以下情况下不起作用:
  • 您正在使用启动器,例如 pm2
  • ,该模块未安装在您的应用程序的 node_modules 中目录(例如,如果您全局安装)

  • 您可以通过设置 APP_ROOT_PATH 来解决此问题。环境变量,或通过调用 .setPath()在模块上,但在这种情况下,您最好使用 global方法。
    NODE_PATH 环境变量
    如果您正在寻找一种方法来确定当前应用程序的根路径,上述解决方案之一可能最适合您。另一方面,如果您正在尝试可靠地解决加载应用程序模块的问题,我强烈建议您查看 NODE_PATH环境变量。
    Node 的 Modules system在不同位置寻找模块。 One of these locations is wherever process.env.NODE_PATH points .如果你设置了这个环境变量,那么你就可以 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 启动您的应用程序而你是金色的。我把它和我的 enforce-node-path 结合起来模块,可防止在没有 NODE_PATH 的情况下意外加载应用程序放。有关强制执行环境变量的更多控制,请参阅 checkenv .
    一个问题: NODE_PATH 必须设置 外面 Node 应用程序。你不能做类似 process.env.NODE_PATH = path.resolve(__dirname) 的事情因为模块加载器会在您的应用程序运行之前缓存它将搜索的目录列表。
    [16 年 4 月 6 日添加] 另一个试图解决这个问题的真正有前途的模块是 wavy .

    关于node.js - 从正在运行的 node.js 应用程序确定项目根,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10265798/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com