0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

モダン開発のディレクトリ構成設計!中大規模プロジェクトでも破綻しない実践的なファイル管理術

0
Posted at

はじめに

🤔「あのコンポーネントどこにあったっけ...」
😱「新機能追加するたびにファイルをどこに置くか迷う...」
💥「プロジェクトが大きくなってディレクトリがカオス状態に!」

そんな経験、ありませんか?

中大規模のプロジェクト開発では、最初のディレクトリ構成の設計が開発効率とメンテナンス性を大きく左右します。

今回は、個人的にさまざまなプロジェクトで試行錯誤してきた結果、現在 最もしっくりきているディレクトリ構成をシェアしたいと思います!
React、Vue、Angular、さらにはバックエンド開発まで、幅広く応用できる考え方だと思うので、Atomic Designで挫折した経験も含めて、現在の私のベストプラクティスをお伝えします!

皆さんはどんな構成でやられていますか?コメントでぜひ教えてください🚀!!!

なぜディレクトリ構成が重要なのか

🎯 中大規模プロジェクトでの課題

小さなアプリでは気にならないディレクトリ構成も、プロジェクトが成長すると途端に問題が顕在化します。

よくある問題例

  • 🔍 ファイル探しに時間がかかる:似たような名前のファイルが散らばっている
  • 🤝 チーム開発での混乱:各メンバーが独自ルールでファイルを配置
  • 🔧 リファクタリングが困難:依存関係が複雑で影響範囲が見えない
  • 📈 技術負債の蓄積:後から整理しようとするとビルドエラーのリスク

💡 事前のルール決めが超重要だと思う理由

個人的にディレクトリ構成のルールは"開発開始前に決めることが一番重要"だと思っています!

ふわふわした状態で開発をスタートすると:

  • メンバーごとに異なるルールでファイルを配置
  • 後から統一しようとすると大幅な構造変更が必要
  • import/exportの修正でビルドエラーのリスク
  • 開発速度の低下とストレス増加

ディレクトリ構成設計の基本原則

💭 私が大切にしている設計の考え方

個人的にディレクトリ構成を設計する際に重視しているポイントは:

  • 目的の明確化: 各ディレクトリが何のためにあるかが一目でわかる
  • 一貫性の維持: チーム全体で共通のルールに従う
  • 拡張性の確保: プロジェクト成長時に破綻しない構造
  • 学習コストの最小化: 新しいメンバーでもすぐに理解できる
  • 関連ファイルの集約: 型やテストなども対象ファイルと一緒に1つのディレクトリで管理

その中でも一番重要に思っているのが「関連ファイルの集約」です!
型はこっち、テストはこっち、と別々の場所に散らばっていると参照しづらいので、関連するファイルは1つのディレクトリに集約されている方が使いやすいと感じています🎲!

実践的ディレクトリ構成の全体像

🏗️ 私の現在のベストプラクティス

これが現在の私のお気に入り構成です! みなさんはいかがでしょうか?

my-project/
├── components/             # UIコンポーネント群(React、Vue等)
│   ├── elements/          # 最小単位(Button、Input等)
│   ├── layouts/           # レイアウト(Header、Footer等)
│   ├── common/            # 共通コンポーネント(ConfirmModal、Dialog等)
│   ├── features/          # 機能単位(UserProfile、ProductCard等)
│   └── pages/             # ページ専用(特定ページのみで使用)
├── hooks/                  # カスタムフック(React)/ composables(Vue)
│   ├── api/               # API関連
│   └── ...                # 汎用ロジック
├── libs/                   # ライブラリ設定・拡張
├── stores/                 # 状態管理(Zustand、Pinia、Redux等)
├── utils/                  # ユーティリティ関数
├── types/                  # 型定義(TypeScript)
├── configs/                # 設定ファイル
├── styles/                 # グローバルスタイル
├── assets/                 # 静的リソース(画像、フォント等)
└── public/                # 公開静的ファイル

UI設計の詳細戦略

🧩 階層別の役割分担

※ 以下はReact/Vue等のコンポーネント指向フレームワークでの例ですが、考え方はバックエンドのモジュール設計にも応用できます

elements/ - 最小単位コンポーネント

components/elements/
├── Button/
│   ├── Button.tsx
│   ├── Button.stories.ts
│   ├── Button.style.ts
│   └── Button.type.ts
├── Modal/
└── Badge/

特徴:

  • 単一責任で再利用性が高い
  • プロジェクト全体で使用される
  • デザインシステムの基盤

layouts/ - レイアウトコンポーネント

components/layouts/
├── Header/
├── Footer/
├── Sidebar/
└── Layout/

特徴:

  • ページ全体の構造を定義
  • ナビゲーション関連
  • 複数ページで共有される枠組み

common/ - 共通機能コンポーネント

components/common/
├── ConfirmModal/
├── LoadingSpinner/
└── ErrorBoundary/

特徴:

  • 機能的で複数箇所で使用
  • ビジネスロジックは含まない
  • UI/UX の共通要素

features/ - 機能単位コンポーネント

components/features/
├── user/
│   ├── UserProfile/
│   └── UserSettings/
├── product/
│   ├── ProductCard/
│   └── ProductList/
├── comment/
│   └── CommentForm/
└── search/
    └── SearchFilter/

特徴:

  • ドメイン別に機能を分類(user、product、comment等)
  • 特定のビジネス領域に特化したコンポーネント群
  • 関連機能をまとめて管理できるため拡張性が高い
  • 複数ページで使用される可能性
  • ビジネスロジックを含む場合がある

pages/ - ページ専用コンポーネント

components/pages/
├── home/
├── login/
└── dashboard/

特徴:

  • 特定ページでのみ使用
  • ディレクトリ名とルートパスを一致させる(/login → login/)
  • 複数ページで使用されるようになったらfeaturesへ移動
  • ページ固有のレイアウトやロジック

🎭 私がAtomic Designを諦めた理由

実際にAtomic Designを導入しようとして困ったこと:

  • 🤷‍♂️ どこに入れればいいか判断に迷う
  • 📱 ページ依存のコンポーネントが汎用的でない
  • 🔄 厳密すぎて現実の開発フローに合わない

現在の構成に落ち着いた理由:

  • ✅ 用途が明確で迷わない
  • ✅ 段階的な昇格(pages → features)が可能
  • ✅ チームメンバーが直感的に理解できる

皆さんはAtomic Design、うまく運用できてますか?

個人的なファイル管理のこだわり

📁 コンポーネントディレクトリの運用方法

個人的に、各コンポーネントは専用ディレクトリを作成して、関連ファイルをまとめて管理するのが気に入っています💘

components/elements/Button/
├── Button.tsx              # メインコンポーネント
├── Button.stories.ts       # Storybookストーリー
├── Button.style.ts         # スタイル定義(Tailwind variants等)
├── Button.type.ts          # 型定義
└── Button.spec.tsx         # テストファイル

メリット:

  • 関連ファイルが一箇所に集約
  • コンポーネント単位でのコード管理
  • 削除時に関連ファイルも一括削除可能

index.tsについて
個人的にはindex.tsは作らない派です。
どのファイルをimportしているかが明確な方が好みで、直接ファイル名を指定してimportしています。
ただし、チームや好みによってはindex.tsで統一する場合もあるので、プロジェクトルールに合わせるのが良いと思います。

🏷️ ファイル命名規則

基本ルール

[ディレクトリ名]/[機能名].[用途].[拡張子]

実践例

configs/
├── color/color.config.ts
├── theme/theme.config.ts
└── api/api.config.ts

types/
├── user/user.type.ts
├── product/product.type.ts
└── common/common.type.ts

utils/
├── cn/cn.util.ts           # classnames utility
├── format/format.util.ts    # 文字列フォーマット
└── validate/validate.util.ts # バリデーション

ドット記法の活用:

  • *.store.ts - ストア定義
  • *.default.ts - デフォルト値
  • *.type.ts - 型定義
  • *.config.ts - 設定ファイル
  • *.util.ts - ユーティリティ関数

各ディレクトリの詳細設計

🎣 hooks/ - カスタムロジック管理

hooks/                      # React例、Vueではcomposables/
├── useAuth/               # Vueではauthに命名
│   ├── useAuth.ts
│   ├── useAuth.type.ts
│   └── useAuth.spec.ts
├── useLocalStorage/
└── api/                    # API専用ロジック
    ├── useGetUser/
    │   ├── useGetUser.ts
    │   ├── useGetUser.type.ts
    │   └── useGetUser.spec.ts
    └── usePostComment/

APIロジックの分離理由:

  • サーバーとの通信を明確に区別
  • キャッシュ戦略の統一管理
  • エラーハンドリングの一元化
  • フレームワーク変更時の影響範囲限定

🗄️ stores/ - 状態管理

stores/
├── user/
│   ├── user.store.ts       # Zustand/Redux store
│   ├── user.default.ts     # 初期値・デフォルト値
│   └── user.type.ts        # ストア関連型
├── cart/
└── theme/

🔧 utils/ - ユーティリティ関数

utils/
├── cn/cn.util.ts           # classNames utility
├── format/
│   ├── format.util.ts
│   └── format.spec.ts
└── api/
    ├── api.util.ts
    └── api.error.ts

⚙️ configs/ - 設定管理

configs/
├── env/env.config.ts       # 環境変数管理
├── database/db.config.ts   # DB設定
└── auth/auth.config.ts     # 認証設定

🎨 styles/ - スタイル管理

styles/
├── globals.scss            # グローバルスタイル
├── animations.scss         # アニメーション定義
└── components.scss         # コンポーネント共通スタイル

注意:

  • stylesディレクトリは例外的にファイル直下配置
  • 内容が少ないため、ディレクトリを作るほどではない

テスト戦略とファイル分割

🧪 テストファイルの効率的な分割

大きなファイルでは、テストも機能ごとに分割して管理性を向上:

hooks/useAuth/
├── useAuth.ts
├── useAuth.signup.spec.ts    # サインアップ関連テスト
├── useAuth.login.spec.ts     # ログイン関連テスト
├── useAuth.logout.spec.ts    # ログアウト関連テスト
└── useAuth.type.ts

メリット:

  • テストファイルの肥大化防止
  • 機能ごとの独立したテスト実行
  • デバッグ時の対象範囲明確化

私がチーム開発で学んだこと

👥 実際に苦労した点と対策

個人的にチーム開発で重要だと感じたポイント:

1. ルール共有の徹底

  • README.mdにディレクトリ構成ルールを明記
  • コードレビューでルール遵守をチェック
  • 新メンバーのオンボーディング資料に含める

2. 段階的な移行戦略

pages → features への昇格例:

1. components/pages/LoginForm/ で開始
2. 他ページでも使用されることが判明
3. components/features/auth/LoginForm/ へ移動(ドメイン別に分類)
4. import文を一括修正

3. 例外ケースのガイドライン

  • どうしても分類に迷う場合の判断基準
  • 暫定的な配置場所の設定
  • 定期的なディレクトリ構成見直しの実施

📋 導入チェックリスト

プロジェクト開始時

  • ディレクトリ構成ルールの文書化
  • チーム全体でのルール共有
  • テンプレートファイルの準備
  • ESLint/Prettierでのimportルール設定

開発中

  • 新規ファイル作成時のルール確認
  • コードレビューでの構成チェック
  • 定期的な構成見直し(月1回程度)

成長時

  • pages → features への移行判断
  • 不要ファイルの定期清掃
  • 新しいディレクトリの必要性検討

まとめ

🎯 個人的に気に入っているポイント

  1. 直感的で迷わない: 用途が明確で判断に迷わない階層設計
  2. 段階的な成長: pages → features の自然な昇格パス
  3. 関連ファイル集約: コンポーネント単位での完結した管理
  4. チーム運用重視: 現実的で持続可能なルール設計

📈 個人的な導入順序

私がプロジェクトを始める時はこの順序で整備することが多いです:

  1. 基本ディレクトリ作成 - components階層の整備
  2. ファイル命名規則統一 - ドット記法の活用
  3. 関連ファイル集約 - コンポーネント単位管理
  4. チームルール策定 - 運用ガイドラインの整備

🚀 個人的に大切にしていること

  • 完璧を求めすぎない: ラフさを持ちつつ一貫性を保つ
  • 段階的な改善: 一気に変更せず徐々に最適化
  • チーム全体の合意: ルールは全員が理解・納得してから導入

最後に

これが現在の私の個人的なベストプラクティスです🤹‍♂️
React、Vue、Next.js、Angular、さらにはNode.js等のバックエンドプロジェクトでも応用できると思っています!

みなさんのディレクトリ構成はどうされていますか?

  • この構成で気になる点はありますか?
  • より良いアイデアがあれば教えてください!
  • 他におすすめの構成があれば知りたいです!

コメントでぜひ議論しましょう✨

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?