gpt4 book ai didi

node.js - ERR_REQUIRE_ESM 来自 webpack 导入 ESM 包

转载 作者:行者123 更新时间:2023-12-05 03:32:21 27 4
gpt4 key购买 nike

我正在使用 Nx 构建应用程序用于模块化和Geckos对于服务器部分。使用 Nx 的 Node 默认 Webpack 5 配置,我在运行应用程序时遇到此错误:

/Users/hgrzeskowiak/hugo-game/fresh-nx-geckos/nx-geckos-test/dist/apps/geckos-server-app/main.js:8
module.exports = require("@geckos.io/server");
^
Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/hgrzeskowiak/hugo-game/fresh-nx-geckos/nx-geckos-test/node_modules/@geckos.io/server/lib/index.js from /Users/hgrzeskowiak/hugo-game/fresh-nx-geckos/nx-geckos-test/dist/apps/geckos-server-app/main.js not supported.
Instead change the require of index.js in /Users/hgrzeskowiak/hugo-game/fresh-nx-geckos/nx-geckos-test/dist/apps/geckos-server-app/main.js to a dynamic import() which is available in all CommonJS modules.
(...)

重现步骤如下:

$ npx create-nx-workspace@latest nx-geckos-test
Need to install the following packages:
create-nx-workspace@latest
Ok to proceed? (y) y
✔ What to create in the new workspace · express
✔ Application name · geckos-server-app
✔ Use Nx Cloud? (It's free and doesn't require registration.) · No

> NX Nx is creating your v13.4.1 workspace.

To make sure the command works reliably in all environments, and that the preset is applied correctly,
Nx will run "npm install" several times. Please wait.

✔ Installing dependencies with npm
✔ Nx has successfully created the workspace.
$ npm run start

> nx-geckos-test@0.0.0 start
> nx serve

> nx run geckos-server-app:serve
chunk (runtime: main) main.js (main) 552 bytes [entry] [rendered]
webpack compiled successfully (26ac6f288b082854)
Debugger listening on ws://localhost:9229/70a1d9b4-af2b-4fc9-90f7-f3502e5fdf2e
Debugger listening on ws://localhost:9229/70a1d9b4-af2b-4fc9-90f7-f3502e5fdf2e
For help, see: https://nodejs.org/en/docs/inspector
Issues checking in progress...
Listening at http://localhost:3333/api

在此阶段,将构建并运行默认的 Express 应用。

现在我将 apps/geckos-server-app/src/main.ts 的内容替换为自述文件中的 Geckos 服务器示例:

import geckos from '@geckos.io/server'

const io = geckos()

io.listen(3000) // default port is 9208

io.onConnection(channel => {
channel.onDisconnect(() => {
console.log(`${channel.id} got disconnected`)
})

channel.on('chat message', data => {
console.log(`got ${data} from "chat message"`)
// emit the "chat message" data to all channels in the same room
io.room(channel.roomId).emit('chat message', data)
})
})

...并使用安装 geckos 服务器包

$ npm install @geckos.io/server

added 4 packages, and audited 785 packages in 7s

87 packages are looking for funding
run `npm fund` for details

found 0 vulnerabilities

好的,是时候再次运行它了:

$ npm run start

> nx-geckos-test@0.0.0 start
> nx serve


> nx run geckos-server-app:serve
chunk (runtime: main) main.js (main) 610 bytes [entry] [rendered]
webpack compiled successfully (90920432a9d246ea)
Debugger listening on ws://localhost:9229/dc6d9e1a-1a15-432f-a46c-d2ac83b923ea
Debugger listening on ws://localhost:9229/dc6d9e1a-1a15-432f-a46c-d2ac83b923ea
For help, see: https://nodejs.org/en/docs/inspector

/Users/hgrzeskowiak/hugo-game/fresh-nx-geckos/nx-geckos-test/dist/apps/geckos-server-app/main.js:8
module.exports = require("@geckos.io/server");
^
Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/hgrzeskowiak/hugo-game/fresh-nx-geckos/nx-geckos-test/node_modules/@geckos.io/server/lib/index.js from /Users/hgrzeskowiak/hugo-game/fresh-nx-geckos/nx-geckos-test/dist/apps/geckos-server-app/main.js not supported.
Instead change the require of index.js in /Users/hgrzeskowiak/hugo-game/fresh-nx-geckos/nx-geckos-test/dist/apps/geckos-server-app/main.js to a dynamic import() which is available in all CommonJS modules.
at Object.@geckos.io/server (/Users/hgrzeskowiak/hugo-game/fresh-nx-geckos/nx-geckos-test/dist/apps/geckos-server-app/main.js:8:18)
at __webpack_require__ (/Users/hgrzeskowiak/hugo-game/fresh-nx-geckos/nx-geckos-test/dist/apps/geckos-server-app/main.js:32:41)
at /Users/hgrzeskowiak/hugo-game/fresh-nx-geckos/nx-geckos-test/dist/apps/geckos-server-app/main.js:45:18
at /Users/hgrzeskowiak/hugo-game/fresh-nx-geckos/nx-geckos-test/dist/apps/geckos-server-app/main.js:59:3
at Object.<anonymous> (/Users/hgrzeskowiak/hugo-game/fresh-nx-geckos/nx-geckos-test/dist/apps/geckos-server-app/main.js:64:12)

我在 package.json 中测试了很多 Webpack 配置覆盖和使用 type: "module",但无济于事。无论我更改什么 webpack 设置,输出 main.js 看起来基本相同。我尝试在应用程序的 webpack 覆盖配置中更改的内容:

module.exports = function(webpackConfig, context) {
webpackConfig.target = "async-node16";
webpackConfig.output.libraryTarget = "module";
webpackConfig.output.library = {type: "module"};
webpackConfig.output.chunkFormat = "module";
webpackConfig.experiments.outputModule = true;
console.log("webpack config:");
console.log(webpackConfig);
console.log("module rules:");
console.log(webpackConfig.module.rules);
return webpackConfig;
}

配置中的控制台登录验证脚本正在运行。

当我手动将转译后的输出中的 require 更改为 import 时,该应用程序可以运行,但这不是一个可持续的解决方案。

我怀疑这个错误与 Geckos 是一个 ESM 包有关,而 Webpack 只使用 require 而不是应有的 import,但我找不到任何改变这种行为的方式。

有什么想法吗?

  • Node 版本 16.13.0
  • Nx 版本 13.4.1
  • Webpack(Nx 的传递依赖):5.65.0

最佳答案

这是我能找到的适用于早于 4.6 的 Type Script 版本的最干净的解决方案(应该添加对此功能的支持)。这实质上是将 ESM 支持修补到具有旧 TypeScript 版本(包括撰写本文时的最新版本)的 WebPack 中。

一个自定义的 Webpack 插件,将外部模块的类型更改为 import

// TypeScript before version 4.6 does not support transpiling ESM imports to
// `import()`, but uses `require()` instead. NodeJS does not support the use
// of `require() for ECMAScript modules (ESM).
//
// Good reads:
// https://www.typescriptlang.org/docs/handbook/esm-node.html
// https://devblogs.microsoft.com/typescript/announcing-typescript-4-5/#esm-nodejs

/**
* A Webpack 5 plugin that can be passed a list of packages that are of type
* ESM. The typescript compiler will then be instructed to use the `import`
* external type.
*/
class ESMLoader {
static defaultOptions = {
esmPackages: "all"
};

constructor(options = {}) {
this.options = { ...ESMLoader.defaultOptions, ...options };
}

apply(compiler) {
compiler.hooks.compilation.tap(
"ECMAScript Module (ESM) Loader. Turns require() into import()",
(
compilation
) => {
compilation.hooks.buildModule.tap("Hello World Plugin", (module) => {
if (
module.type === "javascript/dynamic" &&
(
this.options.esmPackages === "all" ||
this.options.esmPackages.includes(module.request)
)
) {
// All types documented at
// https://webpack.js.org/configuration/externals/#externalstype
module.externalType = "import";
}
}
)
;
}
);
}
}

module.exports = function(webpackConfig, context) {
// NodeJS supports dynamic imports since version 12.
webpackConfig.target = "node16";
webpackConfig.plugins.push(
// Manually specify the ESM modules or leave blank for using `import()`
// on all packages.
//new ESMLoader()
new ESMLoader({esmPackages: "@geckos.io/server"})
);
return webpackConfig;
};

可以通过 project.json 在 Nx 应用程序上设置自定义 webpack 配置:

{
"targets": {
"build": {
"executor": "@nrwl/node:build",
"options": {
...
"webpackConfig": "apps/your-app/webpackConfig.js"
},
...

此解决方案还需要 tsconfig.json 将模块类型设置为比 commonjs 更现代的类型,例如es2020:

{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "es2020",
"types": ["node"],
},
"exclude": ["**/*.spec.ts", "**/*.test.ts"],
"include": ["**/*.ts"]
}

完成此操作后,可以使用通常的 nx serve 运行构建的文件。

关于node.js - ERR_REQUIRE_ESM 来自 webpack 导入 ESM 包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70484934/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com