それを仕組みで防ぐには、どうしますか。レビューで気をつける、以外の方法で。
サーバー専用にしたいファイルの先頭で 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 します。