Jogar Quadro 2.2.x:Estática ativos localização não trabalhar na produção
-
21-12-2019 - |
Pergunta
Tendo problemas para acessar o compilado localização de ativos em produção.
A minha estratégia tem sido a de servir os meus bens em "app/assets/ui" quando em desenvolvimento e o "público", quando na produção de isso é feito, como mostrado abaixo na minha conf/arquivo de rotas
#{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)
#{/}
Desde que eu tenho definido ativos mapeamentos de fora "público", eu adicionei a seguinte linha na minha construção.scala
playAssetsDirectories <+= baseDirectory / "app/assets/ui"
Como um exemplo, o meu scripts são carregados conditionaly dependendo do ambiente, como mostrado abaixo
@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>}
Eu estou usando o Grunhido para o meu frontend de fluxo de trabalho e quando o aplicativo cria, ele copia os arquivos de distribuição para a aplicação de pasta pública.Eu iniciar o aplicativo em produção usando "sbt clean compile stage"
e, em seguida, execute o pacote do aplicativo.
O meu problema parece que as rotas são ainda referindo-se ao "app/assets/ui" em vez da pasta de distribuição "público" pasta.
Alguma dica de como eu posso depurar esse?Minha experiência profissional é como um front-end developer, então eu sou muito novo para Jogar!e scala.
Solução
Como mencionado pelo @estmatic, sua condicional no routes
não serão avaliados.
Como é, geralmente, extremamente úteis para consolidar as diferenças entre a aplicação Mode
s em arquivos, eu sugiro que você estender GlobalSettings
(se você já não estiver) e substituir o onLoadConfig
método:
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)
}
...
}
Em seguida, você poderia ter apropriadamente nomeado arquivos (dev.conf
e production.conf
vêm à mente) que contêm valores adequados, sendo um deles o da base de dados path
para os Ativos controlador de usar.
EDITAR acaba por fazê-lo desta maneira, torna o uso em routes
estranho, aqui está outra abordagem:
Esta abordagem não usa um arquivo de configuração por-meio ambiente, o que significa que, se algo muda na interface de configuração (por exemplo,ele não é mais servido de /public
) você terá que alterar esse código e reimplantá-lo.No entanto, ele se encaixa em Play 2.x muito bem:
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)
}
O código é bem auto-explicativo, o único "truque" é, provavelmente, o lazy val
o que significa que apenas temos de avaliar o modo de funcionamento actual e fazer o mapa de pesquisa de uma só vez.
Agora, o seu routes
arquivo apenas se parece com este:
GET /assets/*file controllers.EnvironmentSpecificAssets.at(file)
Outras dicas
Labbo 2.x não suporta instruções condicionais no arquivo de rotas.1.x versões tinha isso, mas ele foi removido.
O que você tem em seu arquivo de rotas é simplesmente duas rotas com o mesmo URI padrão, /assets/file*
.As outras linhas são apenas sendo ignorado como comentários desde que começam com o caractere de libra, #
.Acho que o padrão é o mesmo para a primeira rota está pegando tudo e o segundo não está fazendo nada.
Não é exatamente o que você está tentando fazer, mas eu acho que você só pode fazer a rota de padrões um pouco diferentes e ele deve funcionar.
GET /assets/dev/*file controllers.common.Assets.at(path="/app/assets/ui", file)
GET /assets/*file controllers.common.Assets.at(path="/public", file)