Open4

ESMで書かれたライブラリをNextで使うと[ERR_REQUIRE_ESM]で落ちる件について

正直よくわかっていない
Nextのトランスパイル後のJSはCJSでパッケージたちを require しようとするが、その読み込み先のライブラリがESMで書かれていると require('path/to/esmodules') になってエラーを吐く

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /project/node_modules/path/to/library/esmodules.js
require() of ES modules is not supported.
require() of /project/node_modules/path/to/library/esmodules.js from /project/.next/server/pages/index.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename esmodules.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /project/node_modules/path/to/library/package.json.

なんとかトランスパイル後のJSで import() を使うようにしたりすることで解決できないか調べたが見つからなかった
(ライブラリのJSたちもトランスパイルの対象に含めるのはがんばればできそうだし確実に解決しそうだけど、大変そうだし重そうだなって思った)

ちなみに今回原因になったESMのライブラリは、Three.js の中の three/examples/jsm/loaders/GLTFLoader.js

とりあえず create-react-app の react-scripts で試したら動いたのでフレームワーク変えることにしました
簡単に解決する方法があったら教えてください…

こんにちは。

自分は Next.js 環境で ky を使用した時に同様のエラーに遭遇しましたが、
next-transpile-modulesを使って、ESM ライブラリ自体もトランスパイルすることで対応できました。
ky も ESM のライブラリなので、同じ感じで解決できるかもです。

yarn add next-transpile-modules
next.config.js
const withTM = require('next-transpile-modules')(['※ESMのライブラリ名']);

module.exports = withTM(/* ご自身のカスタム設定 */);

https://github.com/vercel/next.js/discussions/21252

投稿ありがとうございます

実は上で書いたthree/examples/jsm/loaders/GLTFLoader.js だけではなく three/examples/jsm/controls/OrbitControls.js というモジュールも同様のエラーを吐いていたのですが、提案いただいた方法でOrbitControlはほぼ問題なく動くようになりました

ただGLTFLoaderの方はまた別のエラーで落ちてしまっていて、沼かもしれません

↑で言っている別のエラーは解消できなかったが、とても似た内容でちゃんと動いている例なので共有

プロジェクト作り直してもっと小さい構成で真似したらいけるかなとか、リンク先記事のコメントで紹介されているライブラリを使ったらいけるかもとか思う けど試すのは正直めんどくさい

https://zenn.dev/zabuton2mai/articles/b50cb6f39fa435
ログインするとコメントできます