はじめに
Reactを用いてWEBサイトを構築する過程で、これまでAtomic Designを採用してきました。しかし、Atomic Designにおける判断基準のあいまいさとプロジェクトの複雑性の増加に伴い、その運用が困難になるケースがありました。
この課題に対処するため、2024年02月現在で、bulletproof-reactのアプローチに基づくディレクトリ構造の採用を検討し、ベストプラクティスに沿った構築ができるようにその理解を深める目的で本文書を作成しました。
Atomic Designの課題
Atomic Designでは、以下のような構成が取られます。
src
|
|-- components
| |-- Atoms
| |-- Molecules
| |-- Organisms
|-- Templates
|--Pages ページ
このアプローチには、以下のような複数の課題を感じていました。
-
ファイル数の増加による管理の難しさ
- 多数のコンポーネントが生成され、整理や管理が複雑になる
-
再利用性の確保の難しさ
- コンポーネント間での再利用が計画的に行われず、効率が低下する
-
コンポーネント間の区分が困難
- Atoms、Molecules、Organismsといったカテゴリー分けに曖昧さが生じる
-
共通化による疎結合の欠如と影響範囲の拡大
- コンポーネントが密接に結びつきすぎており、一箇所の変更が広範囲に影響を及ぼすリスクがある
結論
これらの課題に対処するためのアプローチとして、bulletproof-reactの考え方に基づき、機能ごとに区切り、分割する方法が有効だと考えています。
この構造は、以下のように構成されます。
|-- components # 共通で利用できるロジック
|-- features # 各機能ごとのディレクトリ
|-- api # 特定の機能に関連するAPIリクエストとフック
|-- assets # 特定の機能用の静的ファイル
|-- components # 機能スコープ内のコンポーネント
|-- hooks # 機能スコープ内のフック
|-- routes # 機能ページのルートコンポーネント
|-- stores # 機能のステートストア
|-- types # 機能のTypeScriptタイプ
|-- utils # 機能のユーティリティ関数
|-- index.ts # 機能のエントリーポイント、外部で使用されるべき全てをエクスポート]]
|-- ....
-
ロジックに特化したコンポーネントの形成
- 機能ごとに特化したコンポーネントを作成し、再利用性と保守性を高めます
-
相互影響の最小化
- 機能モジュールの独立性により、一箇所の変更が他の機能に及ぼす影響を最小限に抑えます
-
疎結合な構造の実現
- コンポーネント間の依存関係を最小化し、柔軟かつ拡張しやすいアプリケーションアーキテクチャを構築します
-
各機能の適切な利用
- 分割された構造は、開発者が特定の機能を容易に見つけ、利用できるようにします
Bulletproof-Reactのディレクトリ構造について
Bulletproof-Reactのディレクトリ構造は、以下のように整理されています。
src
|
|-- assets # 画像、フォントなど、すべての静的ファイルを含むことができるフォルダ
|-- components # アプリケーション全体で使用される共有コンポーネント
|-- config # すべてのグローバル設定、環境変数などがここからエクスポートされ、アプリで使用れる
|-- features # 機能ベースのモジュール
|-- hooks # アプリケーション全体で使用される共有フック
|-- lib # アプリケーション用に事前設定された異なるライブラリの再エクスポート
|-- providers # アプリケーションのすべてのプロバイダー
|-- routes # ルート設定
|-- stores # グローバルステートストア
|-- test # テストユーティリティとモックサーバー
|-- types # アプリケーション全体で使用される基本タイプ
|-- utils # 共有ユーティリティ関数
詳細説明
assets
ロゴや画像、フォントなどの静的ファイルを含みます。
components
アプリケーション全体で使用される共有コンポーネント、共通のレイアウトやボタン、リンクなどを管理します。
config
アプリケーションの環境変数やグローバル設定を定義します。
features
機能ごとにモジュールを作成し、疎結合な構成を実現します。各機能は以下のように構成されています。
src/features/awesome-feature
|
|-- api # 特定の機能に関連するAPIリクエストとフック
|-- assets # 特定の機能用の静的ファイル
|-- components # 機能スコープ内のコンポーネント
|-- hooks # 機能スコープ内のフック
|-- routes # 機能ページのルートコンポーネント
|-- stores # 機能のステートストア
|-- types # 機能のTypeScriptタイプ
|-- utils # 機能のユーティリティ関数
|-- index.ts # 機能のエントリーポイント、外部で使用されるべき全てをエクスポート
hooks
アプリケーション全体で利用される共有フックを保存します。機能に依存しないものが含まれます。
lib
異なるライブラリの事前設定や再エクスポートを管理します。
providers
エラーハンドリング、非同期データフェッチング、アプリケーションの状態管理など、アプリケーション全体で利用されるプロバイダーを管理します。
routes
アプリケーション全体のルート設定をします。
stores
グローバルステート管理を行います。zustandやreduxなどのライブラリを利用します。
types
アプリケーション全体で使用される基本タイプを定義します。
test
テストユーティリティとモックサーバーを含みます。
utils
全体で利用される便利な関数を配置します。
まとめ
Bulletproof-Reactのディレクトリ構造について、内容理解のため記事を書いてみました。
今後も、プロジェクトを進める上で分からなかった点など記載しようと思います。