https://zenn.dev/temasaguru/articles/0191cf919bd0a3
Next 13のapp
ディレクトリは、React 18のサーバー/クライアントコンポーネントの概念を前提として実装されており、開発者にもその理解が要求されます。そのため、まずは以下のBetaドキュメントを熟読しましょう。
特に注意してほしいのは、イベントリスナーや状態変化を前提としたコンポーネントは、use client
でクライアントコンポーネントだと明示する必要がある点です。
また、明確にgetXXXPropsに分離できていた通信関連の関数を、必ずサーバーコンポーネントから呼ぶ必要が生じます。
import | サーバーコンポーネント(デフォルト) | クライアントコンポーネント(use client ) |
---|---|---|
サーバー想定コード | ✅ | ❌(A: CORSエラーや意図しない漏洩の発生) |
クライアント想定コード | ❌(B: window を使ってしまった等の場合) |
✅ |
この区別を蔑ろにすると、意図しないコードの混入が発生したが、ビルドが通ってしまって気づかない 場合がこれまで以上に増えるでしょう。
この記事ではAとBのパターンで確実にビルドを止める方法を解説していきます。
通信が含まれていれば、大抵はビルド時にCORSエラーで引っかかり気づくのですが、そうならない場合、エラーなくビルドを終えて、page-XXX.js
にサーバー側のコードをバンドルしてしまいます。
例えば上記の関数をgetServerSideProps
からコンポーネントに移動したとしましょう。
NEXT_PUBLIC
無しの環境変数が使われていることから、これを「サーバーサイドで動く前提で書かれたが、説明不足でごっちゃになってしまった」ということにしましょう。
"use client";
import { use } from "react";
import { getDog } from "../lib/get-dog";
const ClientComponent = () => {
const dog = use(getDog());
return <div>{dog}</div>;
};
export default ClientComponent;
次に、use client
を明示したクライアントコンポーネントで上記の関数を使ってみます。
NEXT_PUBLIC
接頭辞がないため環境変数の流出は免れますが、本来バンドルに含まれないはずのコードが丸見えになります。
とにかく想定していない漏洩を発生させないために、そもそもビルド時に例外を投げる方向でいきましょう。