节点 JS (cpanel) 错误:我收到错误 [ERR_REQUIRE_ESM]:必须使用导入来加载 ES 模块



因此,我今天花了相当多的时间尝试将我的nodeJS应用程序完全使用ESM(模块(,并通过cPanel将其部署在使用Node v.14.20.1的服务器上。我经常收到一个错误:

App 1153856 output: internal/modules/cjs/loader.js:948
App 1153856 output:     throw new ERR_REQUIRE_ESM(filename);
App 1153856 output:     ^
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /<serverlocation>/app.js
App 1153856 output:     at new NodeError (internal/errors.js:322:7)
App 1153856 output:     at Module.load (internal/modules/cjs/loader.js:948:11)
App 1153856 output:     at Function.Module._load (internal/modules/cjs/loader.js:790:12)
App 1153856 output:     at Module.require (internal/modules/cjs/loader.js:974:19)
App 1153856 output:     at Module.require (/opt/cpanel/ea-ruby27/root/usr/share/passenger/helper-scripts/node-loader.js:80:25)

所有文件都是作为模块编写的,我没有一个"模块";require((";在任何地方

由于Node从v14开始完全支持JS模块,我猜测我正在使用的托管服务器(以及他们的Passenger for NodeJS(正在使用一个使用";require((";调用我的app.js文件时。我尝试过多种解决方案,我甚至将我的app.js文件切换到了CommonJS类型,但这需要我将所有其他文件也切换到CJS,这会太麻烦了。

有人设法找到这个问题的适当解决方案吗?

对于任何试图解决这个问题的人,我就是这样解决的:

1-创建一个加载程序脚本:不一定和你的应用程序的主app.js文件在同一个文件夹中,但那是我创建它的地方。把它称为loader.cjs。如果你有"类型":"模块";在您的软件包.json中。正如你可能已经猜到的,这将是你应用程序的新主体。由于乘客的加载程序有ES模块的问题,只需让它加载一个commonjs文件即可。

2-app.js的动态导入:你知道你仍然可以在commonjs文件中加载ES模块吗?你只需要多一点就可以了。显然,ES模块是异步加载的,这与同步的commonjs文件不兼容。这就是为什么你一开始就有这个问题,对吧?因此,解决方案是:动态导入。就像异步函数一样,将ES模块的导入视为承诺。我真的不喜欢使用.then((,所以我选择了wait:

async function loadApp() {
await import("/path/to/app.js");
}
loadApp();

3-重命名你的app.js的扩展名:我不知道为什么这是必要的,但我在";找不到/path/to/app.mjs";所以我把它改成了这样。然后它就起作用了。您可以将文件的名称保留为";js";在前一点的路径中,并且导入将sstil正确地查找";app.mjs";;

也许有更有效的方法可以做到这一点,但这正是我的两个大脑所能想到的。希望它也能帮助其他人。

相关内容

最新更新