如何使用项目根目录中的文件路径在 NodeJS 中导入 JavaScript 文件?(而不是相对文件路径)

how*_*d_9 15 javascript require commonjs node.js webstorm

问题:

\n

如何使用项目根目录中的文件路径在 NodeJS 中导入 JavaScript 文件?(而不是相对文件路径)

\n

换句话说,我的团队正在尝试从语法样式 A过渡到语法样式 B(如下所示):

\n

语法风格A

\n
const source = require(\'../../../../../../source.js\');\n
Run Code Online (Sandbox Code Playgroud)\n

语法风格 B

\n
const source = require(\'src/source.js\'); // "src" is a direct subfolder of the project root\n
Run Code Online (Sandbox Code Playgroud)\n

我已经审阅了很多关于这个主题的帖子,但没有一个能够满足我的项目的要求......

\n
\n

项目要求:

\n
    \n
  • 要求#1:没有外部包(例如 Babel.js 或 Webpack),因为磁盘空间有限。另外,我们无法使用“npm install”安装任何东西。
  • \n
  • 要求#2:JavaScript 文件应该能够使用“项目根”文件路径而不是相对文件路径导入另一个 JavaScript 文件。(这将避免诸如“../../../../../../../script.js”之类的长相对路径,这可能会变得难以管理。)
  • \n
  • 要求#3:在源代码中的任意位置右键单击导入的类应该会弹出一个上下文菜单,其中包含“转到声明”选项(这将我们直接带到导入的文件)。此外,将 JavaScript 文件移动到 IDE 中的其他文件夹应该会自动更新所有引用。我们可以使用任何IDE。
  • \n
  • 要求#4:为了采用一致的方式导入脚本,我们将使用 NodeJS 的“require”关键字进行导入(而不是 JavaScript 的“import”关键字)。
  • \n
\n
\n

设置:

\n

以下是我的设置。Package.json是由WebStorm生成的,我没有更改它。

\n

项目结构的屏幕截图

\n
Project_Root\n\xe2\x94\x9c\xe2\x94\x80-\xe2\x94\x80 src\n\xe2\x94\x82    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 a1\n\xe2\x94\x82       \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 a2\n\xe2\x94\x82           \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 a3\n\xe2\x94\x82               \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 Worker.js\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80- subFolder1\n\xe2\x94\x82    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 SubWorker.js\n\xe2\x94\x9c\xe2\x94\x80 main.js\n\xe2\x94\x94\xe2\x94\x80 package.json\n
Run Code Online (Sandbox Code Playgroud)\n
\n

main.js

\n
Project_Root\n\xe2\x94\x9c\xe2\x94\x80-\xe2\x94\x80 src\n\xe2\x94\x82    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 a1\n\xe2\x94\x82       \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 a2\n\xe2\x94\x82           \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 a3\n\xe2\x94\x82               \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 Worker.js\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80- subFolder1\n\xe2\x94\x82    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 SubWorker.js\n\xe2\x94\x9c\xe2\x94\x80 main.js\n\xe2\x94\x94\xe2\x94\x80 package.json\n
Run Code Online (Sandbox Code Playgroud)\n

Worker.js

\n
const Worker = require(\'./src/a1/a2/a3/Worker.js\');\nWorker.doWork();\n
Run Code Online (Sandbox Code Playgroud)\n

SubWorker.js

\n
// If I replace the following with Project Root path, such as:\n//    const SubWorker = require(\'src/subFolder1/SubWorker.js\');\n// The script will fail with "Error: Cannot find module \'./src/subFolder1/SubWorker.js\'."\n\nconst SubWorker = require(\'../../../subFolder1/SubWorker.js\');\n\nmodule.exports =\nclass Worker { \n\n        static doWork() {\n                console.log("doing work");\n                SubWorker.doMoreWork();\n        }\n}\n
Run Code Online (Sandbox Code Playgroud)\n
\n

尝试#1:path.resolve

\n

我尝试了“path.resolve”解决方案,正如这篇文章所建议的:

\n\n
\n

尝试#2:应用程序模块路径

\n
    \n
  • 在带有 ES 模块的 Node.js 中使用相对路径导入\n
      \n
    • 使用app-module-path解决了所有三个要求,但程序将无法运行(这是隐含的要求): \xe2\x9b\x94Error: Cannot find module \'src/subFolder1/SubWorker.js\'
    • \n
    • 在 WebStorm 2022.3.2 和 VS Code 1.76.2 中均可重现错误
    • \n
    \n
  • \n
\n
\n

尝试#3:动态导入()

\n\n

Worker.js

\n
module.exports =\nclass SubWorker {\n\n        static doMoreWork() {\n                console.log("doing more work");\n        }\n\n};\n
Run Code Online (Sandbox Code Playgroud)\n
\n

尝试#4:子路径导入

\n\n
\n

预期结果:

\n

由于 NodeJs 是最重要的后端语言之一,我期待 IDE 对导入提供出色的支持...从项目根引用源文件应该是一个由 IDE 处理的简单操作(我不应该需要使用 Babel) .js 或 Webpack)。我在这里做错了什么吗?

\n

我不知道我做错了什么,因为我已经遵循了标准做法:

\n
    \n
  • 我使用了最流行的 NodeJS IDE 的最新版本(WebStorm 2022.3.2 和 VS Code 1.76.2)
  • \n
  • 我使用 WebStorm 的“创建新 NodeJS 项目”向导来创建项目
  • \n
  • 我使用了最新的 NodeJS (v18.15.0)。(在 Windows 10、v21H2 上)
  • \n
\n

谢谢!

\n
\n

相关文章:

\n

下面的 Stack Overflow 帖子是相关的,但没有解决本文中的具体问题。(请在 Stack Overflow 上按标题搜索,因为垃圾邮件过滤器限制了本文中的链接数量,谢谢!)

\n
    \n
  • 标题:NodeJS - 相对文件路径\n
      \n
    • 失败的方式与我上面的尝试 #1 相同
    • \n
    \n
  • \n
  • 标题:NodeJS 模块的基于项目根的相对路径\n
      \n
    • 违反要求#4(所需的解决方案应使用“require”而不是“import”)
    • \n
    \n
  • \n
  • 标题:是否可以去掉导入时的相对路径?\n
      \n
    • 最佳答案使用 Babel.js,这违反了要求 #1
    • \n
    \n
  • \n
  • 标题:如何将 JavaScript 文件导入到另一个 JavaScript 文件\n
      \n
    • 没有解决相对路径与“项目根”路径的问题
    • \n
    \n
  • \n
  • 标题:如何在 NodeJs 中使用绝对/动态路径\n
      \n
    • 违反要求#4(所需的解决方案应使用“require”而不是“import”)
    • \n
    \n
  • \n
  • 标题:如何在 React 或 Next.js 中使用绝对路径而不是相对路径?\n
      \n
    • 我们在这里没有使用 React 或 Next.js。
    • \n
    \n
  • \n
  • 标题:JavaScript 通过绝对路径导入文件\n
      \n
    • 违反要求#4(所需的解决方案应使用“require”而不是“import”)
    • \n
    \n
  • \n
  • 标题: 具有绝对文件路径的 javascript 文件\n
      \n
    • 这里的脚本是从客户端 Web 浏览器启动的。这篇文章讨论从服务器端后端启动的 NodeJS 脚本。
    • \n
    \n
  • \n
\n
\n

Ari*_*ial 11

使用“导入”属性

截至 2023 年 3 月,消除 NodeJS 相对路径的一个好方法是imports使用package.json. (在下面的代码中,#root 是项目根目录。)


对于 CommonJS 风格的 JavaScript:

// package.json
{
  "imports": {
    "#root/*.js": "./*.js"
  }
}

// main.js:
const Source = require('#root/path/to/Source.js');

// Source.js:
module.exports = class Source {
  // ...
}

Run Code Online (Sandbox Code Playgroud)

对于 ECMAScript 风格的 JavaScript:

// package.json:
{
  "type" : "module",
  "imports": {
    "#root/*.js": "./*.js"
  }
}

// main.js
import { Source } from '#root/path/to/Source.js';

// Source.js:
export class Source {
  // ...
}

Run Code Online (Sandbox Code Playgroud)

优点:

  • 不需要“导入”或“要求”任何额外的包(没有 Babel.js、没有 Webpack、没有 RequireJS)。安装 NodeJS 后,此方法开箱即用。

  • IDE 链接按预期工作(按住 Ctrl 键单击类名可直接跳转到源文件。此外,移动源文件(通过拖放)将自动更新对该文件的所有引用。已在WebStorm 2022.3.2和上测试VS Code 1.76.2。)

  • 适用于.mjs(ECMAScript 模块系统)和.cjs(CommonJS)文件类型。请参阅有关 .cjs 和 .mjs 的参考帖子。

  • 无需修改保留node_modules目录

  • 无需在操作系统级别设置任何 linux 文件链接

2023 年 4 月更新: