[FE] フロントエンドのディレクトリ設計

# 目次
- [アーキテクチャの分割方法](#アーキテクチャの分割方法)
- [Layer型](#Layer型)
    - [Atomic Design](#Atomic-Design)
    - [Component-Based Design](#Component-Based-Design)
    - [Presentation-Container Design](#Presentation-ContainerDesign)
- [Feature型](#Feature型)
    - [Feature Sliced Design](#Feature-Sliced-Design)
    - [Feature Module Design](#Feature-Module-Design)
    - [Redux Ducks Pattern](#Redux-Ducks-Pattern)
    - [Domain-Driven Design](#Domain-Driven-Design)

# アーキテクチャの分割方法
- **Layer型:** 技術によるディレクトリ分割
- **Feature型:** ドメインによるディレクトリ分割

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/4947928a-d7bd-7f78-266b-44651ff416dc.png)

# Layer型
## Atomic Design
UIコンポーネントをその抽象度や複雑度に基づいて階層的に分類します。各レベル（Atoms、Molecules、Organisms、Templates、Pages）ごとにディレクトリが分けられており、技術的な観点からの分割が主となります。

1. **Atoms (原子):** 最小のUI要素（ボタン、インプットフィールドなど）。
2. **Molecules (分子):** 複数のAtomsを組み合わせた小さなコンポーネント（例えば、ラベル付きのインプットフィールド）。
3. **Organisms (有機体):** 複数のMoleculesを組み合わせたより大きなコンポーネント（例えば、ナビゲーションバー）。
4. **Templates (テンプレート):** Organismsを配置してページのレイアウトを作成。
5. **Pages (ページ):** 実際のページコンテンツ。
~~~yaml:src
src/
│
├── components/
│   ├── atoms/
│   │   ├── Button/
│   │   │   ├── Button.js
│   │   │   └── Button.css
│   │   ├── Input/
│   │   │   ├── Input.js
│   │   │   └── Input.css
│   │   └── ...
│   │
│   ├── molecules/
│   │   ├── FormInput/
│   │   │   ├── FormInput.js
│   │   │   └── FormInput.css
│   │   └── ...
│   │
│   ├── organisms/
│   │   ├── Header/
│   │   │   ├── Header.js
│   │   │   └── Header.css
│   │   └── ...
│   │
│   ├── templates/
│   │   ├── MainTemplate/
│   │   │   ├── MainTemplate.js
│   │   │   └── MainTemplate.css
│   │   └── ...
│   │
│   └── pages/
│       ├── HomePage/
│       │   ├── HomePage.js
│       │   └── HomePage.css
│       └── ...
│
└── index.js
~~~
## Component-Based Design
各コンポーネントごとにディレクトリを作成し、その中に関連するファイルを配置します。技術的な観点からの分割が主となり、UIコンポーネント単位で整理されます。
~~~yaml:src
src/
│
├── components/
│   ├── Button/
│   │   ├── Button.js
│   │   └── Button.css
│   ├── Input/
│   │   ├── Input.js
│   │   └── Input.css
│   ├── Header/
│   │   ├── Header.js
│   │   └── Header.css
│   └── ...
│
└── index.js
~~~
## Presentation-Container Design
プレゼンテーションコンポーネントとコンテナコンポーネントを明確に分ける設計手法です。プレゼンテーションコンポーネントはUIの見た目に特化し、コンテナコンポーネントはビジネスロジックやデータの管理を行います。
~~~yaml:src
src/
│
├── components/
│   ├── Presentation/
│   │   ├── Button.js
│   │   ├── Header.js
│   │   └── ...
│   ├── Container/
│   │   ├── HeaderContainer.js
│   │   └── ...
│
└── index.js
~~~

# Feature型
## Feature Sliced Design
機能ごとにディレクトリを分割する手法です。各機能（認証、ダッシュボードなど）ごとにディレクトリを作成し、その中にコンポーネント、フック、状態管理、スタイルシートなどを配置します。ドメインや機能に基づいた分割が主となります。
~~~yaml:src
src/
│
├── features/
│   ├── authentication/
│   │   ├── components/
│   │   │   ├── LoginForm.js
│   │   │   ├── SignupForm.js
│   │   │   └── ...
│   │   ├── hooks/
│   │   │   ├── useAuth.js
│   │   │   └── ...
│   │   ├── store/
│   │   │   ├── authSlice.js
│   │   │   └── ...
│   │   ├── styles/
│   │   │   ├── LoginForm.css
│   │   │   └── ...
│   │   └── ...
│   │
│   ├── dashboard/
│   │   ├── components/
│   │   │   ├── DashboardHeader.js
│   │   │   └── ...
│   │   ├── hooks/
│   │   │   ├── useDashboard.js
│   │   │   └── ...
│   │   ├── store/
│   │   │   ├── dashboardSlice.js
│   │   │   └── ...
│   │   ├── styles/
│   │   │   ├── DashboardHeader.css
│   │   │   └── ...
│   │   └── ...
│   │
│   └── ...
│
└── index.js
~~~
## Feature Module Design
機能ごとにモジュールを作成し、その中に関連するコンポーネント、サービス、スタイルシートなどを配置します。ドメインや機能に基づいた分割が主となります。
~~~yaml:src
src/
│
├── app/
│   ├── app.module.js
│   ├── app.component.js
│   └── ...
│
├── auth/
│   ├── auth.module.js
│   ├── auth.service.js
│   ├── login/
│   │   ├── login.component.js
│   │   └── login.css
│   ├── signup/
│   │   ├── signup.component.js
│   │   └── signup.css
│   └── ...
│
├── dashboard/
│   ├── dashboard.module.js
│   ├── dashboard.service.js
│   ├── dashboard/
│   │   ├── dashboard.component.js
│   │   └── dashboard.css
│   └── ...
│
└── index.js
~~~
## Redux Ducks Pattern
Reduxのアクションタイプ、アクションクリエーター、リデューサーを1つのファイルにまとめる設計手法です。各機能（Duck）ごとにディレクトリを分け、関連するすべてのReduxロジックをその中に含めます。
~~~yaml:src
src/
│
├── features/
│   ├── authentication/
│   │   ├── authenticationDuck.js
│   │   ├── components/
│   │   │   ├── LoginForm.js
│   │   │   └── ...
│   │   └── ...
│   ├── user/
│   │   ├── userDuck.js
│   │   ├── components/
│   │   │   ├── UserProfile.js
│   │   │   └── ...
│   │   └── ...
│
└── index.js
~~~
## Domain-Driven Design
ビジネスロジックやドメイン知識を中心にディレクトリを構造化する手法です。各ドメインごとに関連するエンティティ、リポジトリ、サービスをまとめます。
~~~yaml:src
src/
│
├── domains/
│   ├── user/
│   │   ├── entities/
│   │   │   ├── User.js
│   │   └── repositories/
│   │       ├── UserRepository.js
│   │       └── ...
│   ├── product/
│   │   ├── entities/
│   │   │   ├── Product.js
│   │   └── repositories/
│   │       ├── ProductRepository.js
│   │       └── ...
│
└── index.js
~~~

# 参考リンク
- [ソフトウェアアーキテクチャの基礎 ―エンジニアリングに基づく体系的アプローチ](https://www.amazon.co.jp/dp/4873119820)
- [atomic design](https://bradfrost.com/blog/post/atomic-web-design/)
- [What Is Component Based Development?](https://www.perforce.com/blog/vcs/component-based-development)
- [Feature-Sliced Design](https://feature-sliced.design/)