Comment créer une application Play 2.2 Scala en tant que sous-projet SBT

j'essaie de créer une application Scala comprenant un projet de bibliothèque (appelons cela common ), un projet de serveur D'épargne (appelons cela server ) et un projet D'application web Play (ci-après appelé web ). Tous les trois sont écrits en Scala et construit avec sbt.

ma structure de projet ressemble à ceci:

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

mon fichier build.sbt (simplifié un peu) ressemble à ceci:

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)

le problème avec cela est que le projet racine n'est pas un projet de jeu, de sorte que la commande play ne fonctionne pas (il se trompe avec

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

je peux corriger cela en faisant ressembler le projet root à un projet Play si j'insère la ligne playScalaSettings après la ligne version dans le fichier SBT, mais alors j'ai un autre problème: la commande play run tente d'exécuter le projet root, pas le sous-projet web . Évidemment, le La commande play run ne fonctionne pas dans le sous-répertoire web car il n'y a pas de fichier SBT pour décrire le projet et ses dépendances.

je suis à la recherche d'une solution qui me permet de conserver cette structure de projet (ce qui signifie que le projet Play est l'un des nombreux sous-projets de mon application), tout en conservant toute la chaleur de cadre de jeu comme les mises à jour à chaud lorsque le code change (même le code dans les bibliothèques dépendantes comme common ).

je pensais avoir trouvé la solution en lançant play pour obtenir la console interactive, puis

 project web
 run

ça marche, mais ça ne marche pas sur la ligne de commande. play web/run exécute pour une raison quelconque la commande de niveau racine run , qui comme indiqué ci-dessus ne fonctionne pas parce que l'application racine n'est pas une application de jeu.

Note: une question similaire a été posée dans le contexte de Play 2.0 à Play Cadre en tant que SBT non-Root Module , mais la réponse n'est pas satisfaisante, et je ne pense pas qu'il est encore correct à partir de Play 2.2.

23
demandé sur Community 2013-09-24 01:10:43

2 réponses

si

 play (entering shell)
 project web
 run

fonctionne, alors vous pouvez le faire fonctionner à partir de la ligne de commande:

 play "project web" "run"

vous pouvez faire en ligne de commande Tout ce que vous pouvez faire dans le shell.

j'ai la même structure de projet et c'est la façon de faire qui fonctionne très bien pour moi.

au fait, je ne pense pas que la recharge à chaud soit liée au jeu. C'est la compilation incrémentale qui est fournie par SBT qui est utilisée par Play. La commande play est juste un lanceur SBT piraté, je pense.

La commande suivante fonctionne très bien pour moi:

 sbt "project web" "run"

et il commence le projet de jeu avec recharge à chaud.


je pense que vous pouvez même utiliser

 sbt "project web" "~run"

qui va essayer de recompiler chaque fois que vous changez un fichier source, au lieu d'attendre un rafraîchissement du navigateur, et fera gagner du temps.

14
répondu Sebastien Lorber 2013-09-24 08:17:56

je pense qu'il s'agit d'un bug dans Play 2.2, donc je l'ai signalé comme erreur / :playRunHooks n'est pas défini" on running as web/run . Il semble aussi avoir été fixé dans 2.3.x, il est donc probable qu'il ne sera pas fixé à 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
  )
0
répondu Eugene Yokota 2014-12-11 17:22:54