あるSDKをNext.jsプロジェクトへ組み込む際、dynamic import と ssr: false が必要になった。
「なぜSSRを無効化する必要があるのか?」を調べる中で、SSRやHydrationの仕組みについて理解が深まったので整理する。
一般的なWebアプリの構成
通常のSPA(Reactのみ)の場合は次のような構成になる。
| |
ブラウザ側でReactが動き、必要なデータだけをAPIサーバーから取得する。
HTMLはブラウザ側で生成される。
SSRを使うNext.jsの構成
SSRを利用する場合は、Next.jsサーバーが追加される。
| |
このとき、
- ブラウザはNext.jsサーバーへアクセスする
- Next.jsサーバーがReactコンポーネントを実行する
- HTMLを生成する
- APIサーバーから必要なデータを取得する
- HTMLをブラウザへ返す
という流れになる。
つまり、
HTMLを返しているのはAPIサーバーではなく、Next.jsサーバー。
Next.jsサーバーとは
「Next.jsサーバーって誰がどうやって用意するの?」
例えば本番サーバーへデプロイして
| |
するとNode.js上でNext.jsが起動し、これが「Next.jsサーバー」になる。
別途Node.js用のプロジェクトを作るわけではない。
SSRサーバーを持たない構成もある
Next.jsは必ずNode.jsサーバーを立てる必要があるわけではなく、next export(あるいはoutput: 'export')で静的エクスポートし、本番ではNext.jsサーバーを動かさずに配信する構成も取れる。
| |
この場合、アクセス時にNext.jsサーバーがHTMLを生成しているわけではなく、ビルド時に生成済みの静的ファイルがそのまま配信される。
なぜSDKでエラーになるのか
ブラウザ向けのSDKの中には
- window
- document
などブラウザのAPIを前提にしているものがある。 例えば、Twilio SDK, Teams SDKとか。
しかしビルド中はNode.js環境なので、
| |
は存在しない。
そのため
| |
のようなエラーになる。
そこで
| |
として、ブラウザだけでSDKを読み込むようにしている。
Hydrationとは
Hydrationは、サーバー(またはビルド時)で作られたHTMLに、Reactがイベントなどを結び付ける処理のこと。
イメージすると、
| |
という流れになる。
SSR・SSG・SPAの違い
| 方式 | HTMLを作るタイミング |
|---|---|
| SPA | ブラウザ |
| SSR | リクエストごとにNext.jsサーバー |
| SSG | ビルド時に事前生成 |
今回理解できたこと
- SSRではNext.jsサーバーがHTMLを生成する
- Next.jsサーバーはNext.jsプロジェクト自体が動いているもの
next export(output: 'export')では本番にNext.jsサーバーはいない- ブラウザ専用のSDKが落ちる理由はNode.js環境には
windowが存在しないため dynamic import + ssr: falseでブラウザだけに読み込みを限定できる- HydrationはHTMLへReactのイベント処理を結び付ける仕組み
補足すると、next export は現在のNext.jsでは非推奨となっており、新しいプロジェクトでは output: 'export' を設定して next build を実行する方式が推奨されている。ただし、SSR・SSG・Hydrationの考え方自体はこのまとめの内容で問題ない。
理解度チェック
理解度チェッククイズ(全4問)
問1
SSRを利用するNext.jsの構成で、実際にHTMLを生成しているのはAPIサーバーとNext.jsサーバーのどちらでしょうか?
答え
Next.jsサーバー。APIサーバーはデータを返すだけで、そのデータを使ってReactコンポーネントを実行しHTMLへ変換しているのはNext.jsサーバー側の処理。問2
ブラウザ向けのSDKをそのままNext.jsに組み込むと、ビルド時やnext start実行時にwindow is not definedのようなエラーになることがあります。これはなぜでしょうか?
答え
SSR(サーバーサイドでのReact実行)はNode.js環境で行われ、Node.jsには`window`や`document`といったブラウザAPIが存在しないため。ブラウザAPIを前提にしたSDKのコードがサーバー側でも評価されてしまい、参照エラーになる。問3
Hydrationとは何かを簡潔に説明してください。
答え
サーバー(またはビルド時)で生成済みのHTMLに対して、Reactがイベントハンドラなどを結び付け、ボタンや入力欄が実際に動くようにする処理のこと。問4
SPA・SSR・SSGは最終的にはどれもブラウザにHTML/JSを届けますが、何が本質的に違うのでしょうか?「HTMLがいつ・どこで作られるか」という観点で3つを比較し、それぞれの方式がなぜその選択をしているのか(何を優先しているのか)まで考えて説明してください。