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接頭辞がないため環境変数の流出は免れますが、本来バンドルに含まれないはずのコードが丸見えになります。

ビルドを止めよう

とにかく想定していない漏洩を発生させないために、そもそもビルド時に例外を投げる方向でいきましょう。