こんにちは。
Next.js × microCMSのブログサイトを作成しVercelでデプロイ・公開しているのですが、
2〜3週間前から「トップページとカテゴリ一覧は閲覧できるのに個別記事ページは閲覧できない」という事象が起きていました。
その事象の内容と起きていた原因について記載したいと思います。
発生した事象
Next.js × microCMSのブログサイトで、トップページとカテゴリ一覧は問題なく閲覧できたものの、
個別記事を閲覧すると以下のような画面が表示されました。
その後、Vercel側のログを確認すると以下のようなエラーが発生していました。
Failed to handle /posts/(記事id)?_rsc=(ハッシュ番号a) Error: Failed to load external module jsdom-(ハッシュ番号b) : Error [ERR_REQUIRE_ESM]: require() of ES Module /var/task/node_modules/@exodus/bytes/encoding-lite.js from /var/task/node_modules/html-encoding-sniffer/lib/html-encoding-sniffer.js not supported.
/posts/(記事id)?_rsc=(ハッシュ番号a) の処理に失敗しました。
エラー: 外部モジュール jsdom-(ハッシュ番号b) の読み込みに失敗しました。エラー [ERR_REQUIRE_ESM]: /var/task/node_modules/html-encoding-sniffer/lib/html-encoding-sniffer.js から ESモジュール /var/task/node_modules/@exodus/bytes/encoding-lite.js を require() することはサポートされていません。
この内容を調べてみたところ、
- jsdomの依存パッケージがES Modulesをrequire()で読み込まれていた
- Vercelの実行環境では、CommonJSのコードからES Modulesを require() する機能がサポートされていない
というエラーのようでした。
何が起きていたか
原因となっていた箇所
まずはjsdomが用いられているライブラリをローカルで npm ls jsdomで確認したところ、
isomorphic-dompurify@3.19.0
vitest@4.1.11
がありました。
このうちvitestは本番にデプロイされていないので除外できるためisomorphic-dompurifyが悪さをしていそうです。
記事ページではライブラリの読み込みとして
import DOMPurify from "isomorphic-dompurify";
があり、これが記事ページのみ閲覧できなくなる要因でした。
なぜローカルでは動いているか
本来はNode.js v22.12.0以上ではデフォルトで require による ES Module のインポートがサポートされています。
そのためローカルでは問題なくisomorphic-dompurifyを読み込むことができます。
ですが、VercelのバックエンドではAWS Lambdaが使われており、AWS Lambdaでは--no-experimental-require-moduleフラグによってES Moduleをrequire()で読み込むことが無効化されていました。
そのためVercelではrequire()が効かなくなっているようでした。
対策
端的に言うとVercelの環境下でもES Modulesをrequireで読み込めれば問題は解決します。
CommonJSでrequire()のES Modulesを実行するには--experimental-require-moduleオプションが必要になります。
今回のケースではVercelで--experimental-require-moduleを環境変数として設定することが必要になります。
- Vercelでプロジェクトの「Environment Variables」を選択する
- Key に NODE_OPTIONS、Value に --experimental-require-module フラグを入力する
- Deployment→Redeployで再デプロイする
とすることで、--experimental-require-moduleが有効になり、先述のエラーが解消され記事ページも閲覧できるようになりました。
最後に
VercelのエラーではまずVercelのエラーログを見るのが第一ということを再認識しました。
またES Modules、CommonJS周りの知見が足りていないため調べるいい機会になりました。
参考資料

