Chapter 05

ディレクトリ構造

koga1020
koga1020
2021.12.18に更新

ディレクトリ構造

前提: このガイドでは、入門ガイドの内容を理解し、Phoenixアプリケーションを起動していることを前提としています。

mix phx.new を使用して新しいPhoenixアプリケーションを生成すると、以下のようなトップレベルのディレクトリ構造が構築されます。

├── _build
├── assets
├── config
├── deps
├── lib
│   ├── hello
│   ├── hello.ex
│   ├── hello_web
│   └── hello_web.ex
├── priv
└── test

それらのディレクトリを1つ1つ見ていきましょう。

  • _build - Elixirの一部として提供されている mix コマンドラインツールによって作成されたディレクトリで、すべてのコンパイルアーティファクトを保持しています。"起動ガイド" で見たように、mix はアプリケーションのメインインターフェイスです。Mixを使ってコードをコンパイルしたり、データベースを作成したり、サーバーを起動したりします。このディレクトリはバージョン管理に含めてはならず、いつでも削除できます。このディレクトリを削除すると、アプリケーションをゼロからビルドしなければなりません。

  • assets - JavaScriptやCSSなど、フロントエンドのソースアセットに関連するすべてのものを保管するディレクトリで、esbuild ツールによって自動的に管理されます。

  • config - プロジェクトの設定を格納するディレクトリです。config/config.exs ファイルは設定のエントリーポイントです。このファイルは、config/dev.exs, config/test.exs, config/prod.exs に記述されている、環境固有の設定をインポートします。最後に、config/runtime.exs が実行されますが、これはsecretや他の動的な設定を読むのに最適な場所です。

  • deps - Mixのすべての依存関係があるディレクトリです。すべての依存関係は、mix.exs ファイルの中にある defp deps do 関数定義に記載されています。このディレクトリはバージョン管理に含めてはならず、いつでも削除できます。このディレクトリを削除すると、Mixはすべてのdepsをイチからダウンロードするように強制されます。

  • lib - アプリケーションのソースコードを保持するディレクトリです。このディレクトリは、lib/hellolib/hello_web の2つのサブディレクトリに分かれています。lib/hello ディレクトリは、すべてのビジネスロジックとビジネスドメインを提供します。これは通常、データベースと直接対話します。Model-View-Controller (MVC)アーキテクチャの "モデル" に相当します。lib/hello_web は、この場合はwebアプリケーションを介して、ビジネスドメインを外部に公開する役割を担います。MVCのビューとコントローラーの両方を保持しています。これらのディレクトリの内容については、次のセクションで詳しく説明します。

  • priv - 本番環境では必要だが、ソースコードには直接含まれていないすべてのリソースを保管するディレクトリです。一般的には、データベーススクリプトや翻訳ファイルなどがここに置かれます。デフォルトでは、assets ディレクトリから提供される静的アセットや生成されたアセットもここから提供されます。

  • test - すべてのアプリケーションテストが入っているディレクトリです。多くの場合、lib の中にあるのと同じ構造になっています。

lib/helloディレクトリ

lib/hello ディレクトリはあなたのビジネスドメインのすべてを提供します。私たちのプロジェクトはまだビジネスロジックを持っていないので、このディレクトリはほとんど空です。見つかるのは3つのファイルだけです。

lib/hello
├── application.ex
├── mailer.ex
└── repo.ex

ファイル lib/hello/application.ex は、Hello.Application という名前のElixirアプリケーションを定義しています。これは、Phoenixのアプリケーションは結局のところ、単にElixirのアプリケーションだからです。Hello.Application モジュールは、どのサービスがアプリケーションの一部であるかを定義しています。

children = [
  # Start the Ecto repository
  Hello.Repo,
  # Start the Telemetry supervisor
  HelloWeb.Telemetry,
  # Start the PubSub system
  {Phoenix.PubSub, name: Hello.PubSub},
  # Start the Endpoint (http/https)
  HelloWeb.Endpoint
  # Start a worker by calling: Hello.Worker.start_link(arg)
  # {Hello.Worker, arg}
]

はじめてPhoenixを使用する場合は、今は詳細を心配する必要はありません。今のところ、私たちのアプリケーションは、データベースリポジトリ、プロセスやノード間でメッセージを共有するためのPubSubシステム、そしてHTTPリクエストを効果的に処理するアプリケーションエンドポイントを起動すると言っておけば十分です。これらのサービスは定義された順番で起動され、アプリケーションをシャットダウンするときはいつでも逆の順番で停止します。

アプリケーションについては、Elixir公式ドキュメントのApplicationで詳しく解説しています。

lib/hello/mailer.exファイルには、メールを配信するための主要なインターフェイスを定義したHello.Mailer` モジュールが格納されています。

defmodule Hello.Mailer do
  use Swoosh.Mailer, otp_app: :hello
end

同じ lib/hello ディレクトリに lib/hello/repo.ex があります。これはデータベースへのメインインターフェイスである Hello.Repo モジュールを定義しています。Postgres(デフォルトのデータベース)を使用している場合、以下のようなものが表示されます。

defmodule Hello.Repo do
  use Ecto.Repo,
    otp_app: :hello,
    adapter: Ecto.Adapters.Postgres
end

そして、今のところはこれで終わりです。プロジェクトを進めていくうちに、このディレクトリにファイルやモジュールを追加していきます。

lib/hello_webディレクトリ

lib/hello_web ディレクトリには、アプリケーションのウェブに関連した部分が格納されています。展開すると次のようになります。

lib/hello_web
├── controllers
│   └── page_controller.ex
├── templates
│   ├── layout
│   │   ├── app.html.heex
│   │   ├── live.html.heex
│   │   └── root.html.heex
│   └── page
│       └── index.html.heex
├── views
│   ├── error_helpers.ex
│   ├── error_view.ex
│   ├── layout_view.ex
│   └── page_view.ex
├── endpoint.ex
├── gettext.ex
├── router.ex
└── telemetry.ex

現在 controllerstemplatesviews ディレクトリにあるすべてのファイルは、"起動" ガイドで見た "Welcome to Phoenix!" ページを作成するためのものです。

templateviews のディレクトリを見ると、Phoenixはレイアウトやエラーページを処理するための機能を提供していることがわかります。

これらのディレクトリの他に、lib/hello_web はルートに4つのファイルを持っています。lib/hello_web/endpoint.ex はHTTPリクエストのエントリーポイントです。ブラウザが http://localhost:4000 にアクセスすると、エンドポイントはデータの処理を開始し、最終的には lib/hello_web/router.ex で定義されているルーターにたどり着きます。ルーターは「コントローラー」にリクエストをディスパッチするためのルールを定義し、「ビュー」と「テンプレート」を使ってHTMLページをクライアントへ返すようにします。これらのレイヤーについては次の「リクエストライフサイクル」から始まる他のガイドで詳しく説明しています。

Telemetryを通じて、Phoenixはアプリケーションのメトリクスを収集し、監視イベントを送信できます。lib/hello_web/telemetry.ex ファイルは、テレメトリプロセスを管理するスーパーバイザーを定義しています。このトピックに関する詳細な情報は、Telemetryガイドを参照してください。

最後に、lib/hello_web/gettext.ex ファイルがあり、これはGettextを通じて国際化を提供します。国際化を気にしないのであれば、このファイルとその内容はスキップしても問題ありません。

アセットディレクトリ

assets ディレクトリには、JavaScriptやCSSなど、フロントエンドのアセットに関連するソースファイルが格納されています。Phoenix v1.6以降、アセットのコンパイルにはesbuildを使用していますが、これはesbuildElixirパッケージで管理されています。esbuild との統合は、アプリに組み込まれています。関連する設定は、config/config.exs ファイルにあります。

その他のスタティックアセットは、priv/static フォルダーに格納され、生成されたアセットは priv/static/assets に格納されます。priv/static にあるものはすべて、lib/hello_web/endpoint.ex で設定された Plug.Static プラグによって提供されます。 devモード(MIX_ENV=dev)で動作している場合、Phoenixは assets ディレクトリに加えられた変更を監視し、作業中にブラウザ上のフロントエンドアプリケーションの更新を行います。

注意: mix phx.new を使ってPhoenixアプリをはじめて作成するときに、assets ディレクトリの場所やレイアウトを変更するオプションを指定できます。 実際、Phoenixアプリは独自のフロントエンドツールを持ってくることもできますし、フロントエンドをまったく持たないこともできます(たとえば、APIを書いている場合などに便利です)。 詳しくは mix help phx.new を実行するか、Mixタスクのドキュメントを参照してください。

他のビルドツールを使いたいなど、デフォルトのesbuild統合ではニーズを満たせない場合は、カスタムアセットビルドに切り替えることができます。

CSSについては、PhoenixにはカスタムスタイルとMilligram CSSフレームワークが同梱されており、プロジェクトに必要な最低限の設定を提供します。他のCSSフレームワークの移行は自由です。その他のリファレンスは、asset management ガイドに記載されています。