Node.js 需要一个相对于包根目录的文件
Posted
技术标签:
【中文标题】Node.js 需要一个相对于包根目录的文件【英文标题】:Node.js require a file relative to the root of the package 【发布时间】:2021-05-31 00:55:49 【问题描述】:在 Node.js 中,有什么方法可以在不使用相对路径的情况下从同一个包中获取文件?例如,这是来自ESLint 的代码的 sn-p。
const rule = require("../../../lib/rules/accessor-pairs"),
RuleTester = require("../../../lib/rule-tester");
事实上,我们必须一路走上树 ../../../
才能到达根部,这不仅令人讨厌。它也很脆弱,因为我无法在不更新所有依赖项引用的情况下移动代码。
但不知何故,Node.js 开发人员似乎在过去 10 年中一直在使用它。除了名为require-self 的第三方依赖项之外,我在文档或堆栈溢出中找不到任何解决此问题的内容。我也找不到明确的说法,使用相对路径是文件在同一模块中需要另一个文件的唯一非 hacky 方式。
如果有一种方法可以在 ECMAScript 模块 (ESM) 中指定相对于包根目录的路径,但不能在 CommonJS (CJS) 中指定路径,反之亦然,我也想知道这一点。
需要明确的是,我认为问题没有解决方案。如果有大。否则,我正在寻找权威参考的确认。
【问题讨论】:
过去我通常使用捆绑器解决这个问题,例如via this config 在 Webpack 中,或在其他插件中。您提到的文件移动的其他问题通常由大多数支持 Node 的 IDE 处理。 【参考方案1】:如果您使用 vscode,那么您很幸运 - !!!!!!项目根目录中的 jsconfig.json 为 commonjs、es6、amd、umd 等处理了这个问题
jsconfig.json 文件指定 javascript 语言服务提供的功能的根文件和选项。
jsconfig.json
"compilerOptions":
"module": "commonjs",
"baseUrl": ".",
"paths":
"@rules/*": ["path/to/lib/rules/"]
然后使用别名:
const rule = require('@rules/accessor-pairs'),
RuleTester = require('@rules/rule-tester');
阅读更多: https://code.visualstudio.com/docs/languages/jsconfig
【讨论】:
【参考方案2】:您可以使用包名本身作为包根的“符号链接”。
示例 - foo
包导入相对于 foo
包根目录的 bar
脚本。
package.json
"dependencies":
"foo": "file:./foo"
index.js
const foo = require('foo');
console.log(foo.bar); // prints "hello"
foo/index.js
const bar = require('foo/bar'); // import relative to the package root
module.exports =
bar: bar
foo/bar.js
module.exports = 'hello';
【讨论】:
你知道这个需要最早的版本节点吗?? @nntrn 我能够在node@v10.0.0
和npm@6.14.12
下运行npm install
和node index.js
(使用nvm use 10.0.0
时自动选择)。旧版本失败了npm install
,因为缺少foo/package.json
,我没有深入研究这个错误(例如,是否只添加一个虚拟的package.json就足够了)。【参考方案3】:
不一定是相同的包 - 如果您正在编写库,这将没有用,但如果您正在编写“最终应用程序” - 实际运行的东西:
一个选项:
如果 NODE_PATH 环境变量设置为以冒号分隔的绝对路径列表,则 Node.js 将在这些路径中搜索模块(如果在其他地方找不到它们)。
所以你可以做任何事情:
1.
export NODE_PATH=.
node app.js
NODE_PATH=. node app.js
// app.js (or whatever your entry point is) before *any* require() calls
process.env.NODE_PATH = __dirname;
require('module').Module._initPaths();
或者,另一种方式:
表示 Node.js 进程启动时加载的入口脚本的 Module 对象。
https://nodejs.org/api/modules.html#modules_require_main
所以你可以这样做:
const rule = require.main.require("./lib/rules/accessor-pairs")
您希望它与根相关的任何时候(假设您的项目结构就是这样)。
【讨论】:
以上是关于Node.js 需要一个相对于包根目录的文件的主要内容,如果未能解决你的问题,请参考以下文章