ViteからNext.jsに移行した際にCloudflare Pagesで発生したNode.js互換性エラーの原因と解決方法

Vite を Cloudflare Pages で公開していた環境を Next.js(App Router)へ移行したところ、デプロイ後にブラウザで次のエラー画面が表示された。

Node.JS Compatibility Error
no nodejs_compat compatibility flag set
The page you've requested has been built using @cloudflare/next-on-pages, but hasn't been properly configured.

ローカルでは問題なく動作していたため気づかなかったが、Cloudflare PagesはNode.jsとは異なるランタイムで動作するため、Next.jsの実行には追加の設定が必要だった。

なぜ Vite では問題なく動いていたのに、Next.js ではエラーになったのか?

ViteはCloudflare Pagesの静的ホスティングで問題なく動作する。

一方で、Next.js を Cloudflare 上で動作させる場合は、@cloudflare/next-on-pagesが内部で一部の Node.js API(例:node:async_hooks) に依存したコードを生成する。

Cloudflare Pages / Workersは Node.jsがそのまま動いているわけではなく、独自のEdge Runtime上で動作する

そのため、Next.jsが必要とするNode APIを利用するには、Cloudflare側のランタイムを Node 互換モードに切り替える必要がある。

エラーが発生した原因をまとめると次のとおり。

Vite はこのような Node API の利用を必要としなかったため、問題が起きなかった。

Cloudflare Pages で必要な設定(解決方法)

エラー文にもある通り、Compatibility flags に nodejs_compat を追加することで解決できる。

手順は以下のとおり。

  1. Cloudflare ダッシュボードで Pages プロジェクトを開く
  2. 上部の「設定」を選択
  3. 「ランタイム」の項目の「互換性フラグ」にnodejs_compat を追加
  4. ページ上部のプロダクションとプレビューを切り替え、両方に同じフラグを設定する
  5. 「互換性の日付」が古い場合は、2024年以降の新しめの日付に更新しておく

alt

設定後に再デプロイすると、エラーは消える。

互換性フラグ(Compatibility flags)とは?

Cloudflare Workers / Pagesのランタイム挙動を選択するための設定。

Node API・Web API・仕様のバージョンなど、さまざまな機能レベルを制御する。

nodejs_compat はその中で、Workers ランタイムに 一部の Node.js API を使えるようにするためのモード

ただし、Node の全機能が使えるわけではなく、

などのNode専用モジュールは依然として利用できない。

そのため、Next.jsのコード中でNode専用の機能を使っている場合は、別のエラーが発生する可能性もある。

互換性の日付とは?

Cloudflare Pages / Workers には「互換性の日付(Compatibility Date)」という設定があり、

アプリをどの時点のランタイム仕様で実行するかを指定するためのものである。

Cloudflareの実行環境は継続的に更新されるため、この日付を設定しておくことで、挙動を特定の仕様に固定でき、予期せぬ変更による不具合を防ぐことができる。

Next.js(特に @cloudflare/next-on-pages)では内部で Node.js API を利用するため、互換性日付が古いとランタイムとの不整合が発生し、実行時エラーが起こりやすい。

Cloudflare 公式では、Node.js 互換 API を利用するために 2024-09-23 以降の互換性日付を設定することを推奨している。

next-on-pagesの最低要件自体は「2022-11-30以降」とされているが、実際の動作安定性を考えると、互換性日付はできるだけ新しいものを設定するのが安全である。

まとめ