简体   繁体   English

如何创建一个Play 2.2 Scala应用程序作为SBT子项目

[英]How to create a Play 2.2 Scala application as an SBT sub-project

I am trying to create a Scala application consisting of a library project (let's call this common ), a Thrift server project (let's call this server ) and a Play web application project (hereinafter known as web ). 我正在尝试创建一个Scala应用程序,包括一个库项目(让我们称之为common ),一个Thrift服务器项目(让我们称之为server )和一个Play Web应用程序项目(以下称为web )。 All three are written in Scala and built with sbt. 这三个都是用Scala编写的,并用sbt构建。

My project structure looks like this: 我的项目结构如下所示:

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

My build.sbt file (simplified a bit) looks like this: 我的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)

The problem with this is that the root project is not a Play project, so the play command does not work (it errors out with 这个问题是根项目不是Play项目,所以play命令不起作用(它出错了

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

I can fix this by making the root project look like a Play project if I insert the line playScalaSettings after the version line in the SBT file, but then I have another problem: the play run command attempts to run the root project, not the web subproject. 如果我在SBT文件中的version行之后插入playScalaSettings行,我可以通过使根项目看起来像Play项目来解决这个问题,但是我有另一个问题: play run命令尝试运行根项目,而不是web子项目。 Obviously the play run command does not work when run in the web subdirectory since there is no SBT file there to describe the project and its dependencies. 显然,当在web子目录中运行时, play run命令不起作用,因为那里没有SBT文件来描述项目及其依赖项。

I am looking for a solution that allows me to retain this project structure (meaning the Play project is one of many sub-projects in my application), while retaining all the Play framework hotness like hot updates when code changes (even code in dependent libraries like common ). 我正在寻找一种解决方案,允许我保留这个项目结构(意味着Play项目是我的应用程序中的许多子项目之一),同时保留所有Play框架热点,如代码更改时的热更新(甚至依赖库中的代码)像common )。

I thought I found the solution by running play to get the interactive console, and then 我以为我通过运行play找到解决方案来获取交互式控制台,然后

 project web
 run

That works, but it doesn't work on the command line. 这可行,但它在命令行上不起作用。 play web/run for some reason runs the root level run command, which as noted above does not work because the root application is not a Play application. play web/run由于某种原因运行root level run命令,如上所述,由于根应用程序不是Play应用程序,因此无效。

Note: A similar question was asked before in the context of Play 2.0 at Play Framework as SBT Non-Root Module , but the answer is not satisfactory, nor do I believe it is still correct as of Play 2.2. 注意:之前在Play Framework中将 Play 2.0 作为SBT非根模块提出了类似的问题,但答案并不令人满意,我认为从Play 2.2开始,它仍然没有问题。

if 如果

 play (entering shell)
 project web
 run

works, then you can make it work from the command line: 工作,然后您可以从命令行使其工作:

 play "project web" "run"

You can do in command line whatever you can do in the shell. 您可以在命令行中执行shell中的任何操作。

I have the same project structure and it is the way to do that works fine for me. 我有相同的项目结构,这是我的工作方式。

By the way, I don't think the hot reload stuff is related to Play. 顺便说一句,我不认为热重载的东西与Play有关。 It is incremental compilation that is provided by SBT which is used by Play. 它是由SBT提供的增量编译,由Play使用。 The play command is just some hacked SBT launcher I think. 我认为play命令只是一些被攻击的SBT发射器。

The following command works fine for me: 以下命令对我来说很好:

 sbt "project web" "run"

And it starts the Play project with hot reload. 它通过热重载启动Play项目。


I think you can even use 我想你甚至可以使用

 sbt "project web" "~run"

Which will try to recompile each time you change a source file, instead of waiting for a browser refresh, and will make win some time. 每次更改源文件时都会尝试重新编译,而不是等待浏览器刷新,并且会赢得一些时间。

I think this is a bug in Play 2.2, so I reported it as Error " / :playRunHooks is undefined" on running as web/run . 我认为这是Play 2.2中的一个错误,因此我在运行为web / run时将其报告为错误“ / :playRunHooks未定义” Also it seems to have been fixed in 2.3.x, so likely it won't be fixed for 2.2. 它似乎已在2.3.x中修复,因此很可能不会修复2.2。 Here's a bit nerdy workaround I came up with: 我提出了一些讨厌的解决方法:

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
  )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM