IT-Q

それを仕組みで防ぐには、どうしますか。レビューで気をつける、以外の方法で。

サーバー専用にしたいファイルの先頭で server-only を import します。Client Component から import された時点でビルドが失敗するので、レビュー頼みでなくなります。

面接官が見ているのは規律ではなく機械で止める発想があるか。

これは「APIキーを使う関数を lib/data.ts に書いていたら、それが Client Component から import されていました。何が起きますか。」への追撃質問です。

よくある答えと、面談でどう見られるか

  • server-only を import しておき、クライアントから import された時点でビルドを落とす
    公式が推奨している方法です。失敗が本番ではなくビルド時に出るのが利点です。
  • ファイル名やディレクトリの命名規則を決めて、レビューで確認する
    あった方が良い実践ですが、設問は「レビュー以外で」です。人は入れ替わりますし、規約は読まれません。機械で止める手段を持っておきたいところです。
  • すべてのサーバー用ファイルに 'use server' を付ける
    役割が違います。'use server' はクライアントから呼べるサーバー関数を作る宣言で、むしろ公開範囲を広げる方向です。防御にはなりません。
  • 変数名を NEXT_PUBLIC_ から始めないようにする
    それは前提であって、この事故は「付けていない」状態でも起きます。問題は import の経路であって、変数名ではありません。

面接官は何を見ているか

  • server-only パッケージを挙げた
  • ビルドを落とす(早い段階で気づく)点を評価できた
  • 「気をつける」では再発すると認識している

模範解答

server-only パッケージを使います。

サーバー専用にしたいファイルの先頭で import 'server-only' と書いておくと、そのモジュールが Client Component から import された時点でビルドが落ちます。公式が推奨している方法です。

これが効くのは、失敗が「本番で認証エラー」ではなく「ビルドエラー」になる点です。一番安いタイミングで、一番わかりやすい形で気づけます。

レビューで気をつける運用にしない理由は、人が入れ替わるからです。規約はドキュメントに書いても読まれませんが、ビルドが落ちれば必ず気づきます。

同じ発想で、共有される可能性のあるユーティリティは「サーバー専用」「クライアント専用」「どちらでも安全」を意識して置き場所を分けます。境界を曖昧にしたまま共有ディレクトリに置くと、いつか誰かが import します。