Pregunta

Tener problemas para acceder a la ubicación de los activos compilados en producción.

Mi estrategia ha sido servir mis activos en "app/assets/ui" cuando están en desarrollo y "públicos" cuando están en producción. Esto se hace como se muestra a continuación en mi archivo 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)
#{/}

Como definí asignaciones de activos fuera de "público", agregué la siguiente línea en mi Build.scala

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

Como ejemplo, mis scripts se cargan condicionalmente según el entorno, como se muestra a continuación.

@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>}

Estoy usando Grunt para mi flujo de trabajo frontend y cuando la aplicación se compila, copia los archivos de distribución a la carpeta pública de la aplicación.Inicio la aplicación en producción usando "sbt clean compile stage" y luego ejecute la aplicación empaquetada.

Mi problema parece que las rutas todavía se refieren a la carpeta "app/assets/ui" en lugar de a la carpeta "pública" de distribución.

¿Algún consejo sobre cómo puedo depurar esto?Mi experiencia laboral es como desarrollador front-end, ¡así que soy muy nuevo en Play!y escala.

¿Fue útil?

Solución

Como lo mencionó @estmatic, tu condicional en routes no será evaluado.

Como generalmente es extremadamente útil consolidar las diferencias entre la aplicación Modes en archivos, te sugiero que extiendas GlobalSettings (si aún no lo has hecho) y anula el 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)
  }
  ...
}

Entonces podría tener archivos con el nombre apropiado (dev.conf y production.conf me vienen a la mente) que contienen valores adecuados, siendo uno de ellos la base path para que lo utilice el controlador de activos.

EDITAR resulta que hacerlo de esta manera hace que se use en routes incómodo, aquí hay otro enfoque:

Este enfoque no utiliza un archivo de configuración por entorno, lo que significa que si algo cambia en la configuración del frontend (p. ej.ya no se sirve desde /public) tendrás que cambiar este código y volver a implementarlo.Sin embargo, encaja bastante bien en 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)
}

El código se explica por sí mismo, el único "truco" es probablemente el lazy val lo que significa que solo tenemos que evaluar el modo de funcionamiento actual y realizar la búsqueda en el mapa una vez.

Ahora tu routes el archivo se ve así:

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

Otros consejos

Playframework 2.x no admite declaraciones condicionales en el archivo de rutas.Las versiones 1.x tenían esto pero fue eliminado.

Lo que tienes en tu archivo de rutas son simplemente dos rutas con el mismo patrón de URI, /assets/file*.Las otras líneas simplemente se ignoran como comentarios ya que comienzan con el carácter de almohadilla. #.Creo que dado que el patrón es el mismo para ambas, la primera ruta capta todo y la segunda no hace nada.

No es exactamente lo que intentas hacer, pero creo que puedes hacer que los patrones de ruta sean un poco diferentes y debería funcionar.

GET   /assets/dev/*file   controllers.common.Assets.at(path="/app/assets/ui", file)
GET   /assets/*file       controllers.common.Assets.at(path="/public", file)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top