Documentation

§公開アセットを扱う

この節は JavaScript, CSS と画像などのアプリケーションの静的リソースの提供をカバーします。

Play で public リソースを提供することは、他の HTTP リクエストにサービスを提供することと同じです。コントローラ/アクションのパスが使う通常のリソースと同じルーティングを使って、クライアントに CSS, JavaScript や画像ファイルを配布します。

§public/ フォルダ

規約により、公開アセットはアプリケーションの public フォルダに格納されます。このフォルダは好きなように構成できます。以下の構成がおすすめです:

public
 └ javascripts
 └ stylesheets
 └ images

このフォルダ構成に従えば簡単に始められますが、どのように動作するか理解している場合は、自由に変更できます。

§WebJars

WebJars は、Activator や sbt の一部となっている、便利で規約化されたパッケージング機構を提供します。例えば、ビルドファイルに以下のように依存性を追加するだけで、ポピュラーな Bootstrap ライブラリ を使うことができます。

libraryDependencies += "org.webjars" % "bootstrap" % "3.3.4"

利便性のため、WebJar は依存性を公開アセットフォルダから見た lib 関連パスに自動的に展開します。例えば、RequireJs の依存性を宣言している場合、以下のようにしてビューから参照することができます:

<script data-main="@routes.Assets.at("javascripts/main.js")" type="text/javascript" src="@routes.Assets.at("lib/requirejs/require.js")"></script>

lib/requirejs/require.js パスに注目してください。この lib フォルダは展開された WebJar アセットを示し、requirejs フォルダは WebJar アーティファクト ID に対応していて、そして require.js が、この WebJar のルートにある要求されたアセットを参照しています。

§公開アセットはどのようにパッケージングされる?

ビルドプロセス中に public フォルダの内容が処理され、アプリケーションのクラスパスに追加されます。

アプリケーションをパッケージングすると、サブプロジェクトを含むすべてのアプリケーションのアセットが単一の target/my-first-app-1.0.0-assets.jar に集約されます。この jar はディストリビューションに含まれるので、Play アプリケーションはこれらのアセットを提供することができます。この jar はアセットを CDN やリバースプロキシにデプロイすることもできます。

§アセットコントローラ

Play には、公開アセットを提供する組み込みのコントローラが付属しています。このコントローラはデフォルトでキャッシュ機能、ETag, gzip, そして圧縮をサポートします。

このコントローラはデフォルトの Play JAR において controllers.Assets として利用可能であり、引数を二つ持つ at アクションを定義しています:

Assets.at(path: String, file: String)

path のパラメータは固定されており、アクションによって管理されるディレクトリを定義する必要があります。 通常、file パラメータはリクエストパスから動的に抽出されます。

以下は、conf/routes ファイルにおける Assets コントローラの典型的なマッピングです:

GET  /assets/*file        controllers.Assets.at(path="/public", file)

*file を正規表現 .* にマッチする動的な部分として定義したことに注目してください。このため、例えば次のようなリクエストをサーバに送信した場合:

GET /assets/javascripts/jquery.js

ルータは次のパラメータを使用して Assets.at アクションを起動します:

controllers.Assets.at("/public", "javascripts/jquery.js")

このアクションは、リクエストされたファイルを探し、そのファイルが存在する場合は提供します。

§公開リソースのリバースルーティング

routes ファイルにマッピングされた任意のコントローラと同様に、リバースコントローラが controllers.routes.Assets に作成されます。公開リソースを取得するために必要な URL をリバースする際に使用します。テンプレートでの例は以下のようになります:

<script src="@routes.Assets.at("javascripts/jquery.js")"></script>

以下の結果を生成します。

<script src="/assets/javascripts/jquery.js"></script>

ルートをリバースする際は folder パラメータを指定しないことに注意してください。これは、folder 引数が固定されている Assets.at アクションのマッピングをひとつ、ルートファイルに定義しているためです。そのため、指定する必要はありません。

しかし、 Assets.at アクションにマッピングをふたつ定義している場合、次のようにしてください:

GET  /javascripts/*file        controllers.Assets.at(path="/public/javascripts", file)
GET  /images/*file             controllers.Assets.at(path="/public/images", file)

リバースルータを使用する場合は、パラメータを両方指定する必要があります:

<script src="@routes.Assets.at("/public/javascripts", "jquery.js")"></script>
<img src="@routes.Assets.at("/public/images", "logo.png")" />

§リバースルーティングと公開アセットへのフィンガープリント

sbt-web は、例えば以下のビルドファイルのように、高度に設定可能なアセットパイプラインの概念を Play に持ち込みました:

pipelineStages := Seq(rjs, digest, gzip)

上記の場合、RequireJs オプティマイザ (sbt-rjs), ダイジェスト (sbt-digest) と、続けて圧縮 (sbt-gzip) が順序付けられます。多くの sbt タスクとは異なり、これらのタスクは宣言された順序で、ひとつずつ実行されます。

アセットのフィンガープリントにより、ブラウザに対して提供する静的なアセットのキャッシュを積極的に指示することができます。結果として、次にサイトを訪れるユーザはより少ないアセットのダウンロードを要求することになり、ユーザ体験が向上します。Rails も アセットのフィンガープリント の利点を述べています。

はじめに、上記した pipelineStages と、必要なプラグインを plugins.sbtaddSbtPlugin で宣言します。続いて、バージョン管理するアセットを Play に宣言する必要があります。以下の route ファイルでは、すべてのアセットをバージョン管理するよう宣言しています:

GET  /assets/*file  controllers.Assets.versioned(path="/public", file: Asset)

file: Asset と書くことで file がアセットであると示していることを確認してください。

それから、例えば scala.html ビューでリバースルーターを使います:

<link rel="stylesheet" href="@routes.Assets.versioned("assets/css/app.css")">

アセットフィンガープリントの利用を強く推奨します。

§Etag サポート

Assets コントローラは、自動的に ETag HTTP ヘッダを管理します。ETag の値 (sbt-digest がアセットパイプラインで使われている場合) は、ダイジェストまたはリソース名および最終更新日付から生成されます。リソースが JAR ファイルに組み込まれている場合は、その JAR ファイルの最終更新日付が使用されます。

Web ブラウザがこの ETag を指定してリクエストを行った場合、サーバは 304 NotModified で応答することができます。

§Gzip サポート

名前が同じで gz 拡張子を持つリソースが見つかった場合、Assets コントローラは後者のリソース、そして以下の HTTP ヘッダを提供します:

Content-Encoding: gzip

gzip ファイルを生成するには、ビルドに sbt-gzip プラグインを取り込み、pipelineStages において適切に宣言している必要があります。

§Cache-Control 命令の追加

通常のキャッシュ目的であれば、ETag で十分です。特定のリソース用に独自の Cache-Control ヘッダを指定したい場合は、application.conf ファイルに指定することができます。例えば:

# Assets configuration
# ~~~~~
"assets.cache./public/stylesheets/bootstrap.min.css"="max-age=3600"

§管理アセット

Play 2.3 から、管理アセットは sbt-web ベースのプラグインで処理されるようになりました。2.3 より前の Play には、管理アセットの処理として CoffeeScript, LESS, JavaScript Lint (ClosureCompiler) そして RequireJS による最適化がバンドルされていました。以降の節では、sbt-web と 2.2 同等の機能を達成する方法について記述します。とは言え、徐々に sbt-web で多くのプラグインが使えるようになっていくため、Play はこのアセット処理技術に制限されていないことに注意してください。sbt-web プロジェクトを確認して、利用できるより多くのプラグインについて学んでください。

多くのプラグインが sbt-web の js-engine plugin を使います。js-engine は、素晴らしい Trireme プロジェクトによって JVM 上でも、またはより良いパフォーマンスのために直接 Node.js 上でも Node API で書かれたプラグインを実行することができます。これらのツールは開発サイクルにおいてのみ使用され、Play アプリケーションの実行時には関与しないことに注目してください。Node.js がインストール済みであれば、以下の環境変数を宣言することを推奨します。Unix で SBT_OPTS をどこかに定義している場合、以下のように指定することができます:

export SBT_OPTS="$SBT_OPTS -Dsbt.jse.engineType=Node"

上記の宣言は、あらゆる sbt-web プラグインの実行時に Node.js が使われることを保証します。

Next: CoffeeScript を使う


このドキュメントの翻訳は Play チームによってメンテナンスされているものではありません。 間違いを見つけた場合、このページのソースコードを ここ で確認することができます。 ドキュメントガイドライン を読んで、お気軽にプルリクエストを送ってください。