質問

本番環境でコンパイルされたアセットの場所にアクセスできない。

私の戦略は、開発時は「app/assets/ui」でアセットを提供し、運用時は「public」で提供することであり、これは私のconf/routesファイルで以下に示すように行われます。

#{if(play.Play.mode.isDev())}
  GET     /assets/*file    controllers.common.Assets.at(path="/app/assets/ui", file)
#{/}
#{else}
  GET     /assets/*file controllers.common.Assets.at(path="/public", file)
#{/}

アセット マッピングを「public」の外側に定義したため、Build.scala に次の行を追加しました。

playAssetsDirectories <+= baseDirectory / "app/assets/ui"

例として、私のスクリプトは以下に示すように環境に応じて条件付きでロードされます。

@if(play.Play.isDev()) {<script src="@routes.Assets.at("/app/assets/ui", "javascripts/application.js")"type="text/javascript"></script>} else {<script src="@.routes.Assets.at("/public", "javascripts/application.min.js")" type="text/javascript"></script>}

フロントエンド ワークフローに Grunt を使用しており、アプリケーションがビルドされると、配布ファイルがアプリケーションのパブリック フォルダーにコピーされます。次を使用して実稼働環境でアプリを起動します "sbt clean compile stage" 次に、パッケージ化されたアプリを実行します。

私の問題は、ルートが依然としてディストリビューションの「public」フォルダーではなく「app/assets/ui」フォルダーを参照しているようです。

これをデバッグする方法について何かヒントはありますか?私の職歴はフロントエンド開発者なので、Play についてはまったくの初心者です。そしてスカラ。

役に立ちましたか?

解決

@estmaticで述べたように、条件式は routes 評価されないよ。

一般に、アプリケーション間の違いを統合することは非常に便利です。 Modeファイルに分割されている場合は、拡張することをお勧めします GlobalSettings (まだオーバーライドしていない場合)、 onLoadConfig 方法:

class Settings extends GlobalSettings {

  override def onLoadConfig(config: Configuration, path: File, classloader: ClassLoader, mode: Mode.Mode): Configuration = {

    val specificConfig:Config =  // ... Use the mode param to load appropriate file        

    super.onLoadConfig(specificConfig, path, classloader, mode)
  }
  ...
}

その後、適切な名前のファイルを作成できます (dev.conf そして production.conf 適切な値が含まれており、そのうちの 1 つはベースです path アセットコントローラーが使用するもの。

編集すると、この方法で使用できることがわかりました routes 厄介ですが、別のアプローチがあります。

このアプローチでは、環境ごとの構成ファイルを使用しません。つまり、フロントエンド構成で何かが変更された場合 (例:もう提供されていません /public) このコードを変更して再デプロイする必要があります。ただし、Play 2.x には非常にうまく適合します。

package controllers

object EnvironmentSpecificAssets extends AssetsBuilder {

  val modeToAssetsPathMap = Map(
    Mode.Dev -> "/app/assets/ui",
    Mode.Prod -> "/public")

  lazy val modePath = modeToAssetsPathMap(Play.current.mode)

  /** New single-argument `at`, determines its path from the current app mode */
  def at(file:String): Action[AnyContent] = at(modePath, file)
}

コードは非常に一目瞭然ですが、唯一の「トリック」はおそらく lazy val つまり、現在の動作モードを評価し、マップ検索を 1 回行うだけで済みます。

今あなたの routes ファイルは次のようになります。

GET   /assets/*file     controllers.EnvironmentSpecificAssets.at(file)

他のヒント

PlayFramework 2.xはルートファイル内の条件文をサポートしません。1.xバージョンはこれを持っていましたが、削除されました。

routesファイルにあるものは、同じURIパターン、/assets/file*を持つ2つのルートです。他の行は、ポンド文字、#で始まるため、コメントとして無視されています。私は最初のルートの両方がすべてをキャッチしているのでパターンが同じであると思います、そして2番目は何もしていません。

あなたがしようとしていることは正確ではありませんが、私はあなたがルートパターンを少し異なるようにすることができ、それは仕事をするべきです。

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top