Play Framework 2.2.x:静态资产位置不在生产中

时间:2014-02-25 15:31:39

标签: scala playframework playframework-2.2

无法访问生产中的已编译资产位置。

我的策略是在开发时使用“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"在生产环境中启动应用程序,然后运行打包的应用程序。

我的问题似乎是路由仍然是指“app / assets / ui”文件夹而不是分发“public”文件夹。

有关如何调试此问题的任何提示?我的工作背景是作为前端开发人员,所以我是Play的新手!和斯卡拉。

2 个答案:

答案 0 :(得分:1)

如@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.confproduction.conf),其中一个是Assets控制器要使用的基础path

EDIT结果这样做会让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,这意味着我们只需要评估当前的操作模式并进行一次地图查找。

现在您的routes文件看起来像这样:

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

答案 1 :(得分:0)

Playframework 2.x不支持routes文件中的条件语句。 1.x版本有这个,但它已被删除。

您的路线文件中只有两条路径具有相同的URI模式/assets/file*。其他行只是作为注释被忽略,因为它们以磅字符#开头。我认为,因为第一条路线捕捉一切都是一样的,第二条路线没有做任何事情。

这并不是你想要做的,但我认为你可以让路线模式有点不同,它应该有效。

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