Подтвердить что ты не робот

Как создать приложение Play 2.2 Scala в качестве подпроекта SBT

Я пытаюсь создать приложение Scala, состоящее из проекта библиотеки (позвольте этому common), проект сервера Thrift (позвоните по этому server) и проекту веб-приложения Play (далее по тексту web). Все три написаны в Scala и построены с помощью sbt.

Моя структура проекта выглядит следующим образом:

myproject/
-common/
  ...
-server/
  ...
-web/
  -app/
  -conf/
  ...
-project/
  -Build.scala
  -build.properties
-build.sbt

Мой build.sbt файл (упрощенный бит) выглядит следующим образом:

import play.Project._

name := "myproject"

version := "1.0-SNAPSHOT"

lazy val common = project

lazy val web = project
    .settings(playScalaSettings: _*)
    .dependsOn(common)

lazy val server = project
    .dependsOn(common)

lazy val root = project.in(file("."))
    .aggregate(common, web, server)

Проблема с этим заключается в том, что корневой проект не является проектом Play, поэтому команда play не работает (с ошибкой

java.lang.RuntimeException: */*:playRunHooks is undefined.
at scala.sys.package$.error(package.scala:27)

Я могу исправить это, сделав корневой проект похожим на проект воспроизведения, если я вставляю строку playScalaSettings после строки version в SBT файл, но тогда у меня есть другая проблема: команда play run пытается запустите проект root, а не подпроект web. Очевидно, что команда play run не работает при запуске в подкаталоге web, так как для описания проекта и его зависимостей нет SBT файла.

Я ищу решение, которое позволяет мне сохранить эту структуру проекта (это означает, что Play-проект является одним из многих подпроектов в моем приложении), сохраняя при этом всю динамику платформы Play как горячие обновления при изменении кода (даже код в зависимых библиотеках, таких как common).

Я думал, что нашел решение, запустив play, чтобы получить интерактивную консоль, а затем

 project web
 run

Это работает, но он не работает в командной строке. play web/run по какой-то причине запускает команду root run, которая, как указано выше, не работает, потому что корневое приложение не является приложением Play.

Примечание. Аналогичный вопрос задавался ранее в контексте Play 2.0 на Play Framework в качестве SBT Non-Root Module, но ответ не является удовлетворительным и не делает Я считаю, что он по-прежнему прав, как в Play 2.2.

4b9b3361

Ответ 1

если

 play (entering shell)
 project web
 run

работает, тогда вы можете заставить его работать из командной строки:

 play "project web" "run"

Вы можете сделать в командной строке все, что вы можете сделать в оболочке.

У меня такая же структура проекта, и это способ сделать это отлично работает для меня.

Кстати, я не думаю, что горячая перезагрузка связана с Play. Это инкрементная компиляция, предоставляемая SBT, которая используется Play. Я думаю, что команда воспроизведения - это просто взломанный пусковой механизм SBT.

Следующая команда отлично работает для меня:

 sbt "project web" "run"

И он запускает проект Play с горячей перезагрузкой.


Я думаю, вы даже можете использовать

 sbt "project web" "~run"

Что будет пытаться перекомпилировать каждый раз, когда вы меняете исходный файл, вместо того, чтобы ждать обновления браузера, и выиграете некоторое время.

Ответ 2

Я думаю, что это ошибка в Play 2.2, поэтому я сообщил об этом как Ошибка "/: playRunHooks is undefined" при запуске как web/run. Также, похоже, оно исправлено в 2.3.x, поэтому, вероятно, оно не будет исправлено для 2.2. Здесь немного проворное обходное решение, которое я придумал:

lazy val root = (project in file(".")).
  settings(
    playRunHooks := Nil,
    playInteractionMode := play.PlayConsoleInteractionMode,
    playDefaultPort := 9000,
    playMonitoredFiles := (Def.taskDyn {
      val s = state.value
      s.history.current.split("/").headOption match {
        case Some(ref) =>
          Def.task {
            (playMonitoredFiles in LocalProject(ref)).value
          }
        case _ =>
          Def.task {
            playMonitoredFiles.value
          }
      } 
    }).value
  )