NodeJS 模块的基于项目根目录的相对路径

Project root based relative paths for NodeJS modules

在我的 NodeJS 项目中处理模块包含,我总是在指定所需项目的其他模块文件的路径方面遇到一些困难。

我明明用的是相对路径。但这意味着做这样的事情:

const helper = require("../../lib/util/helpers.js

这有一些缺点:

  1. 我总是需要考虑放置我需要另一个模块的文件的位置。

  2. 随着项目的增长,由于项目重组,我偶尔需要将一些文件移动到另一个地方,所以我不仅需要审查需要它的文件的路径,还需要审查所有需要的模块的路径我正在移动的文件。

我一直认为如果我可以指定相对于项目根目录而不是文件本身的路径会更清楚。明确地说,那是我的 package.json 文件(或 node_modules 目录)所在的位置。

我知道我可以使用 require.resolve() 解析任何外部模块的路径,虽然我可以做类似 path.dirname(path.dirname(path.dirname(require.resolve('express')))) 的事情,但它对我来说太脏了。

不幸的是,据我所知,没有任何 require.modules_pathrequire.projectRoot 属性 所以我需要依靠我上面提到的一些技巧或遍历整个树直到包含 package.json 文件的第一个父目录。

我的问题是:有没有我遗漏的更好的解决方案?

通过使用运行时符号将项目的根路径存储为 process 对象的 属性,我找到了一个甚至不完美的可接受的解决方案。

Using a symbol to name that property we avoid any possibility of colliding with another process object properties, even with future ones.

我所做的只是将这两行添加到我的 app.js(在 Express 项目中,它被放置在项目根目录中,并且从主应用程序入口点 bin/www 需要,我也确保了它是第一个必需的依赖项):

const $root = Symbol.for("projectRoot");                                         │     return new Promise(function (resolve, reject) {
process[$root] = __dirname;

在那之后,我在所有其他模块中唯一需要做的就是在最开始重复第一行:

const $root = Symbol.for("projectRoot");

...并在所有 require 语句中使用它。例如:

const helper = require(process[$root]+"/lib/util/helpers.js

也许它远非完美,但它对我有用...