🐈

Flutterアプリのプロジェクト構成を解説

2024/10/16に公開

はじめに

プロジェクトのディレクトリ構成はコードの可読性や保守性に大きく影響します。
特にプロジェクトが成長するにつれて、整理された構成は開発効率を高め、バグの発見や修正を容易にする鍵となります。

適切なディレクトリ構成を採用することで開発チーム全体が一貫したコーディングスタイルを維持し、コードの品質を保つことができます。

本記事では、Flutterプロジェクトにおけるディレクトリ構成の例をご紹介します。

また、今回ご紹介するプロジェクト構成は前提としているアーキテクチャがあります。
別の記事で解説しているので、未読の方はそちらを参照してください。

プロジェクト構成

プロジェクト構成
[project_root]/
├── assets/
├── env/
├── lib/
│   ├── main.dart
│   └── src/
│       ├── root.dart
│       ├── api/
│       │   ├── api_impl.dart
│       │   ├── interface/
│       │   │   └── api.dart
│       │   └── response/
│       │       └── [xxx]_response.dart
│       ├── app_state/
│       │   └── [xxx]_state.dart
│       ├── framework/
│       │   ├── di/
│       │   │   ├── interface/
│       │   │   │   └── service_locator.dart
│       │   │   └── service_locator_impl.dart
│       │   ├── error/
│       │   │   ├── errors.dart
│       │   │   └── result.dart
│       │   ├── module/
│       │   │   ├── interface/
│       │   │   │   └── [xxx].dart
│       │   │   └── [xxx]_impl.dart
│       │   └── util/
│       ├── model/
│       │   └── [xxx].dart
│       ├── repository/
│       │   ├── interface/
│       │   │   └── [xxx]_repository.dart
│       │   └── [xxx]_repository_impl.dart
│       ├── router/
│       │   ├── route_path.dart
│       │   ├── router_config.dart
│       │   └── routes.dart
│       ├── screen/
│       │   └── [xxx]/
│       │       ├── [xxx]_screen.dart
│       │       └── [xxx]_view_model.dart
│       ├── service/
│       │   ├── interface/
│       │   │   └── [xxx]_service.dart
│       │   └── [xxx]_service_impl.dart
│       ├── theme/
│       │   └── theme.dart
│       ├── view_controller/
│       │   ├── [xxx]_impl.dart
│       │   └── interface/
│       │       ├── [xxx].dart
│       │       └── [xxx].dart
│       └── widget/
│           ├── container/
│           │   └── [xxx]
│           │       └── [xxx].dart
│           └── presentation/
│               └── [xxx]
│                   └── [xxx].dart
└── test/
    ├── e2e/
    └── unit/

flutter createコマンドで生成されるディレクトリで配置を変えないものは省略しています。

  • レイヤーファーストの構造でアーキテクチャの各コンポーネントを中心に配置
  • 階層が深くなりすぎないように配慮

assets/

  • 画像やフォントなどのリソースファイルを配置
  • 公式ドキュメントを参考にしてプロジェクトルートに配置

env/

  • ビルド時に渡す定数や環境変数を管理
  • 環境ごとにファイルを分ける
  • --dart-define-from-fileに渡すので.json.envの好きな方でいい

lib/main.dart

  • アプリのエントリーポイントになるソースファイル
  • 一番最初に参照されるのでlibの直下に配置

lib/src/

  • dartにおいて外部に公開されないコードを配置
  • main.dartとそれ以外の関係を明確にするためにsrcを挟む

lib/src/root.dart

  • runAppに渡すウィジェットツリーのルートになるウィジェット
  • 他のウィジェットとの関係を明確にするためにlib/srcの直下に配置

lib/src/api/

  • API通信に関するコードを配置
  • APIのモックを想定してinterfaceを切る
  • レスポンスの定義はコード量が増えがちなので、responseに分ける

lib/src/app_state/

  • アプリ全体で共有される状態を管理
  • riverpodのkeepAlive: trueで常に保持される

lib/src/framework/

  • 各レイヤーで共通して利用するコードを配置
  • framework/直下は適切な名前でディレクトリを切る

lib/src/model/

  • アプリで扱うドメインのデータモデルを配置
  • モデルにはビジネスロジックを持たせない

lib/src/repository/

  • データの永続化や外部APIとの通信を行うコードを配置

lib/src/router/

  • ルーティングに関するコードを配置

lib/src/screen/

  • 画面ごとのウィジェットとViewModelを配置
  • screen/直下は画面ごとにディレクトリを切る
  • 画面ごとにディレクトリには[xxx]_screen.dart[xxx]_view_model.dart以外にも専用のウィジェットのソースを配置してもいい

lib/src/service/

  • アプリケーションで利用するビジネスロジックを配置

lib/src/theme/

  • アプリケーション全体で利用するテーマやUIスタイルを定義

lib/src/view_controller/

  • ViewModelで利用するUIロジックを分離するためのコードを配置

lib/src/widget/

  • 各画面で利用する共通ウィジェットを配置
  • presentationcontainerに分ける
    • presentationは表示するデータをパラメータとして受け取り、表示のみを行うウィジェット
    • containerは表示するデータを取得するためのロジックを持ち、取得したデータをpresentationウィジェットに渡す
    • presentationcontainerの中はそれぞれUIの種類ごとにディレクトリを切る

test/

  • テストコードを配置
  • ユニットテストとE2Eテストを分けて配置

ローカルパッケージを利用する場合

アプリをプロジェクトルートに配置したまま

[project_root]/
├── lib/
└── packages/
    └── [other_package]/
        └── lib/
  • アプリのプロジェクトルートにpackagesディレクトリを作成して、その配下に各ローカルパッケージを配置
  • ciやタスクランナー等でディレクトリパスが変わると困る場合に有効

モノレポ構成

[project_root]/
└── packages/
    ├── [app]/
    │   └── lib/
    └── [other_package]/
        └── lib/
  • 各パッケージをpackagesディレクトリに配置
  • モノレポ用のツールが使える

まとめ

Flutterプロジェクトにおけるディレクトリ構成の例をご紹介しました。

アーキテクチャを明確にし、それに合わせた構成を採用することで開発効率を向上させ、コードの品質を保つことができます。

また、プロジェクトの成長に合わせてディレクトリ構成を見直すことも重要です。
開発メンバーの入れ替わりやアーキテクチャに影響のある変更を行う際に、プロジェクト構成を見直すとより効果的に変更を適用できるでしょう。

最後に、この記事で紹介したプロジェクト構成が少しでも参考になれば幸いです。

参考資料

Discussion