Возникли проблемы с доступом к расположению скомпилированных ресурсов в рабочей среде.
Моя стратегия заключалась в том, чтобы обслуживать мои активы в "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! и скала.
Ответ 1 · рейтинг 1 · millhouse
Как уже упоминалось @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)
Ответ 2 · estmatic
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)