Next.jsプロジェクトを「迷宮」にしない:Feature-based(機能単位)設計の極意

日笠泰彰の記事

はじめに

プロジェクトの初期段階では、components/hooks/ といった「役割別」のディレクトリ構成で十分かもしれません。しかし、機能が増えるにつれ、それらは巨大な「ゴミ箱」へと変貌し、特定の機能を修正するためにプロジェクト全体を横断してファイルを探し回る羽目になります。

この問題を解決するのが、Feature-based(機能単位)設計です。

1. Feature-based 設計とは?

Feature-based 設計とは、コンポーネントの種類(Atomic Designなど)で分けるのではなく、「ユーザーに提供する機能(ドメイン)」ごとにコードを凝集させる設計手法です。

例えば、「ブログ記事(post)」に関するコンポーネント、フック、型定義、API通信は、すべて一つの features/post/ ディレクトリに集約します。

2. 推奨されるディレクトリ構造

App Router を使用する場合、以下のような構成が理想的です。

Plaintext

src/
  app/         # ルーティング(Next.js固有)
  components/  # ボタンや入力欄など、プロジェクト共通のUI(UIライブラリ的なもの)
  features/    # ここが主役!
    auth/      # ログイン・会員登録機能
    post/      # 記事投稿・一覧・詳細機能
      components/  # postだけで使うコンポーネント(PostCardなど)
      hooks/       # postだけで使うロジック
      types/       # post関連の型定義
      api/         # microCMS等との通信ロジック
      index.ts     # 外部へ公開するエントリーポイント(公開設定)

3. Feature-based 設計のメリット

① 認知負荷の激減

「記事の投稿ボタンを直したい」と思ったら、迷わず features/post/ を開けばいいだけです。他の機能に影響を与える心配が少なく、心理的な安全性が高まります。

② 不要になった機能の削除が容易

もし「コメント機能(comment)」が不要になったら、features/comment/ ディレクトリを削除するだけで、関連するコードを一掃できます。

③ 依存関係の可視化

features/post/ の中から features/auth/ を参照している場合、機能間の依存関係が明確になります。循環参照などの設計ミスにも気づきやすくなります。

4. 運用上のルール:index.ts によるカプセル化

Feature-based 設計を成功させるコツは、各 feature の直下に index.ts を置き、「外部に公開していいもの(Public API)」を制限することです。

TypeScript

// features/post/index.ts
export * from './components/PostList';
export * from './types';
// 内部だけで使う hooks などは export しない

これにより、他チームや将来の自分が、意図しない内部実装に依存してしまうのを防げます。

まとめ

Feature-based 設計は、Next.js プロジェクトの保守性を劇的に向上させます。最初は手間に感じるかもしれませんが、ディレクトリ構成が整うことで、開発スピードと記事更新の「加速」が現実のものとなります。

著者プロフィール

日笠泰彰
ITエンジニアとして活動し、RailsやNext.jsを中心としたモダンなWeb開発を得意とする。