Play Framework 2.2.x: местоположение статических ресурсов не работает в рабочей среде

Возникли проблемы с доступом к расположению скомпилированных ресурсов в рабочей среде.

Моя стратегия заключалась в том, чтобы обслуживать мои активы в «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)
#{/}

Поскольку я определил сопоставление активов вне «общедоступного», я добавил следующую строку в свой 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», а не к «общедоступной» папке дистрибутива.

Любые советы о том, как я могу отладить это? Мой опыт работы — фронтенд-разработчик, поэтому я новичок в Play! и скала.


person Anthony Munene    schedule 25.02.2014    source источник


Ответы (2)


arrow_upward
1
arrow_downward

Как уже упоминалось @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), которые содержат подходящие значения, одно из которых является базовым path для использования контроллером Assets.

Оказывается, 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)
person millhouse    schedule 26.02.2014
comment
Спасибо, теперь это имеет смысл, и я не знал, что условные выражения больше не поддерживаются в Play 2.x. Не могли бы вы уточнить, как я могу включить базовый путь в свой контроллер активов? Мой контроллер текущих активов показан ниже. package controllers.common object Assets extends controllers.AssetsBuilder - person Anthony Munene; 26.02.2014
comment
Спасибо, это именно то, что мне было нужно. - person Anthony Munene; 05.03.2014

arrow_upward
0
arrow_downward

Playframework 2.x не поддерживает условные операторы в файле маршрутов. В версиях 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)
person estmatic    schedule 25.02.2014