如何使用 Phusion Passenger 纠正此 ESM 错误?

Del*_*rak 10 javascript passenger node.js node-modules

我正在尝试使用 Phusion Passenger 在生产服务器上启动我的 NodeJS API。我使用了最后的 ECM 语法来导入/导出我的模块。然而,当尝试访问我的 api 时,Passenger 返回此错误消息:

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /home/***/api/server.mjs
    at Module.load (internal/modules/cjs/loader.js:948:11)
    at Function.Module._load (internal/modules/cjs/loader.js:790:14)
    at Module.require (internal/modules/cjs/loader.js:974:19)
    at Module.require (/opt/passenger/src/helper-scripts/node-loader.js:80:25)
    at require (internal/modules/cjs/helpers.js:92:18)
    at loadApplication (/opt/passenger/src/helper-scripts/node-loader.js:243:2)
    at setupEnvironment (/opt/passenger/src/helper-scripts/node-loader.js:214:2)
    at Object.<anonymous> (/opt/passenger/src/helper-scripts/node-loader.js:133:1)
    at Module._compile (internal/modules/cjs/loader.js:1085:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10) {
  code: 'ERR_REQUIRE_ESM'
Run Code Online (Sandbox Code Playgroud)

我的 package.json 中有该"type": "module"行,我尝试将扩展名从 .js 更改为 .mjs,但没有效果。

我注意到,乘客使用带有“require”语法的 CJS 来加载我的 server.js,如下所示: https: //github.com/phusion/passenger/blob/stable-6.0/src/helper-scripts/node-loader .js

function loadApplication() {
    var appRoot = PhusionPassenger.options.app_root || process.cwd();
    var startupFile = PhusionPassenger.options.startup_file || (appRoot + '/' + 'app.js');
    require(startupFile);
}
Run Code Online (Sandbox Code Playgroud)

所以我的问题是:有没有办法不将我的所有代码从 ECM 更改为 CJS 以与 Passenger 匹配?

Les*_*ers 13

对上面代码的更新 - 这对我来说不起作用,除非异步调用动态导入:

创建一个entry.cjs 文件并使用 async/await 动态导入您通常在 plesk 中设置的应用程序入口文件:

// entry.cjs
async function loadApp() {
    const { app } = await import("./app.js"); // this is your normal entry file - (index.js, main.js, app.mjs etc.)
}
loadApp()
Run Code Online (Sandbox Code Playgroud)

然后在 Plesk 中将您的应用程序入口文件设置为 ./entry.cjs


小智 8

有一种方法:考虑到你所有的文件都有.mjs扩展名,你只需要创建一个.js作为Passenger的入口文件,在这个文件(CommonJS格式)中你可以动态导入ESM文件。

因此,不要node server.mjs通过 Passenger 运行,而是创建一个entry.js包含以下内容的:

import("./server.mjs");
Run Code Online (Sandbox Code Playgroud)

然后node entry.js通过Passenger调用。

注意:您可以为该entry.js文件使用任何其他名称。