播放框架2.2。x:静态资产位置在生产中不起作用
-
21-12-2019 - |
题
在生产中无法访问已编译的资产位置。
我的策略是在开发时在"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"之外定义了资产映射,因此我在构建中添加了以下行。斯卡拉
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"文件夹。
关于如何调试这个的任何提示?我的工作背景是作为一个前端开发者,所以我很新玩!还有斯卡拉。
解决方案
如@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
spring to mind)包含合适的值,其中一个是基础 path
供资产控制人使用。
编辑原来这样做使用法在 routes
尴尬,这是另一种方法:
这种方法不使用每个环境的配置文件,这意味着如果前端配置发生变化(例如它不再是从 /public
)您必须更改此代码并重新部署它。然而,它适合发挥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)
其他提示
Playframework2。x不支持routes文件中的条件语句。的1。x版本有这个,但它被删除。
您在routes文件中拥有的只是具有相同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)