§サブプロジェクト
複雑なプロジェクトを、ひとつの Play アプリケーションにまとめる必要はありません。大きなプロジェクトを小さないくつかのアプリケーションに分割したり、Play アプリケーションと関係のないロジックは標準的な Java や Scala のライブラリを抽出したくなることがあるでしょう。
マルチプロジェクト・ビルドについての SBT ドキュメント を読むといいでしょう。サブプロジェクトは独自のビルドファイルを持たず、親プロジェクトのビルドファイルを共有します。
§ライブラリをサブプロジェクトとして切り出す
アプリケーションをシンプルなライブラリプロジェクトに依存させることができます。build.sbt
に、次のような sbt のプロジェクト定義を追加してください:
name := "my-first-application"
version := "1.0"
lazy val myFirstApplication = (project in file("."))
.enablePlugins(PlayScala)
.aggregate(myLibrary)
.dependsOn(myLibrary)
lazy val myLibrary = project
最終行の小文字の project
は、代入先の val の名前を使ってプロジェクトの名前とフォルダを決定する Scala マクロです。
この myFirstApplication
は、ベースプロジェクトを宣言します。サブプロジェクトを持たない場合は特に設定する必要はありませんが、サブプロジェクトを持つ場合は宣言する必要があり、これによりベースプロジェクトがサブプロジェクトを集約 (つまり、ベースプロジェクトを実行すると、サブプロジェクトがコンパイル/テストされます) し、またサブプロジェクトに依存 (つまり、サブプロジェクトをベースプロジェクトのクラスパスに追加します) することを確認できます。
上記の例では myLibrary
ディレクトリにサブプロジェクトを定義しました。サブプロジェクトは普通の sbt プロジェクトの一種であり、標準的なディレクトリ構成に従います:
myProject
└ build.sbt
└ app
└ conf
└ public
└ myLibrary
└ build.sbt
└ src
└ main
└ java
└ scala
myLibrary
にも、独自の設定や依存性などを宣言する、専用の build.sbt
ファイルがあります。
ビルド設定でサブプロジェクトを有効にした場合、それぞれのプロジェクトを個別にコンパイル、テスト、実行することができます。Play コンソールで projects
コマンドを実行すると、全てのプロジェクトが表示されます:
[my-first-application] $ projects
[info] In file:/Volumes/Data/gbo/myFirstApp/
[info] * my-first-application
[info] my-library
デフォルトのプロジェクトは変数名がアルファベット順で最初の物になります。メインプロジェクトを指定したい場合は変数名を aaaMain 等にする事で可能になります。現在のプロジェクトを切り替えるには、project
コマンドを使ってください:
[my-first-application] $ project my-library
[info] Set current project to my-library
>
Play アプリケーションを開発モードで起動している場合、依存するサブプロジェクトも自動的に再コンパイルされます。サブプロジェクトのコンパイルエラーも、ブラウザ上で確認できます:
§共通変数とコードの共有
ルートプロジェクトとサブプロジェクトで共通の設定やコードを共有したい場合は、ルートプロジェクトの project
内の Scala ファイルに配置することができます。例えば、次のような project/Common.scala
があるとします:
import sbt._
import Keys._
object Common {
val settings: Seq[Setting[_]] = Seq(
organization := "com.example",
version := "1.2.3-SNAPSHOT"
)
val fooDependency = "com.foo" %% "foo" % "2.4"
}
こうすることで、すべての build.sbt
から、このファイルに定義されたあらゆるものを参照できるようになります:
name := "my-sub-module"
Common.settings
libraryDependencies += Common.fooDependency
§Webアプリケーションを複数のプロジェクトに分割する
Play アプリケーションの実体は、デフォルトの設定を持った標準的な sbt プロジェクトなので、他の Play アプリケーションに依存することができます。対応する build.sbt
ファイルに、プロジェクトが Java または Scala いずれのプロジェクトであるかに応じて PlayJava
もしくは PlayScala
プラグインを追加することで、あらゆるサブモジュールを Play アプリケーションにすることができます。
注意: 名前の衝突を避けるために、サブプロジェクト内の Assets コントローラを含むコントローラが、メインプロジェクトとは異なる名前空間を使っていることを確認してください。
§ルートファイルを分割する
route ファイルを、より小さなファイルに分割することもできます。この機能は、堅牢で、再利用性の高いマルチモジュール Play アプリケーションを作るときにとても便利です。
§以下のビルド設定を検討してみましょう
build.sbt
:
name := "myproject"
lazy val admin = (project in file("modules/admin")).enablePlugins(PlayScala)
lazy val main = (project in file("."))
.enablePlugins(PlayScala).dependsOn(admin).aggregate(admin)
modules/admin/build.sbt
name := "myadmin"
libraryDependencies ++= Seq(
"mysql" % "mysql-connector-java" % "5.1.35",
jdbc,
anorm
)
§プロジェクト構成
build.sbt
app
└ controllers
└ models
└ views
conf
└ application.conf
└ routes
modules
└ admin
└ build.sbt
└ conf
└ admin.routes
└ app
└ controllers
└ models
└ views
project
└ build.properties
└ plugins.sbt
注意: 設定ファイルおよび route ファイルの名前はプロジェクト構成全体でユニークでなければならず、
application.conf
ファイルとroutes
ファイルはそれぞれひとつだけです。サブプロジェクトに routes または設定ファイルを定義する場合は、サブプロジェクトに特化した名前を使います。例えば、admin
中の route ファイルはadmin.route
と呼ばれます。開発モードのサブプロジェクトにおいて特別な設定セットを使う際、例えばPlayKeys.devSettings += ("play.http.router", "admin.Routes")
.のように、その設定セットをビルドファイルに書くとなお良いでしょう。
conf/routes
:
GET /index controllers.Application.index()
-> /admin admin.Routes
GET /assets/*file controllers.Assets.at(path="/public", file)
modules/admin/conf/admin.routes
:
GET /index controllers.admin.Application.index()
GET /assets/*file controllers.admin.Assets.at(path="/public/lib/myadmin", file)
注意: リソースは単一のクラスローダから提供されるので、リソースパスはルートプロジェクトのクラスパスから見た相対パスでなければなりません。
サブプロジェクトのリソースはtarget/web/public/main/lib/{module-name}
に生成されるので、Assets.at
メソッドが行っているようにplay.api.Application#resources(uri)
を使った場合、そのリソースには/public/lib/{module-name}
でアクセスできるようになります。
§アセットとコントローラクラスは controllers.admin
パッケージ以下に無ければなりません
modules/admin/controllers/Assets.scala
:
package controllers.admin
import play.api.http.LazyHttpErrorHandler
object Assets extends controllers.AssetsBuilder(LazyHttpErrorHandler)
Java のユーザは、以下のようにして同様のことを実現できます:
// Assets.java
package controllers.admin;
import play.api.mvc.*;
public class Assets {
public static Action<AnyContent> at(String path, String file) {
return controllers.Assets.at(path, file);
}
}
コントローラも同様です:
modules/admin/controllers/Application.scala
:
package controllers.admin
import play.api._
import play.api.mvc._
import views.html._
object Application extends Controller {
def index = Action { implicit request =>
Ok("admin")
}
}
§admin
でのリバースルーティング
通常のコントローラの場合は以下のように呼び出します:
controllers.admin.routes.Application.index
Assets
の場合は以下のようにします:
controllers.admin.routes.Assets.at("...")
§ブラウザ経由の場合
http://localhost:9000/index
上記 URL は、以下を呼び出します。
controllers.Application.index
また
http://localhost:9000/admin/index
上記 URL は、以下を呼び出します。
controllers.admin.Application.index
Next: Play エンハンサ
このドキュメントの翻訳は Play チームによってメンテナンスされているものではありません。 間違いを見つけた場合、このページのソースコードを ここ で確認することができます。 ドキュメントガイドライン を読んで、お気軽にプルリクエストを送ってください。