Play! 2.0框架多模块项目

3
我需要有两个不同的项目,比方说内部和外部,它们使用相同的数据层,并且我想为了干燥(DRY)的原因避免复制配置文件。
我已经查看了子项目文档 http://www.playframework.org/documentation/2.0.2/SBTSubProjects,但是文档很简短。
现在我意识到可以通过模块化配置来实现,感谢 @Georg Engel。
import sbt._
import Keys._
import PlayProject._

object ApplicationBuild extends Build {

    val appName         = "MyApp"
    val appVersion      = "1.0-SNAPSHOT"

    val appDependencies = Seq(
      // Add your project dependencies here,
    )

    lazy val common = Project(appName + "-common", file("modules/common"))

    lazy val website = PlayProject(
    appName + "-website", appVersion, path = file("modules/website")
    ).dependsOn(common)

    lazy val adminArea = PlayProject(
    appName + "-admin", appVersion, path = file("modules/admin")
    ).dependsOn(common)

    lazy val main = PlayProject(appName, appVersion, appDependencies, mainLang = SCALA).settings(
      // Add your own project settings here      
    ).dependsOn(
    website, adminArea
    )


}

只有因为反向路由器(取消路由但未取消控制器操作会导致此问题),我遇到的编译错误。

1
我建议使用聚合函数...常见的项目似乎根本没有编译。您必须在子项目中提供路由文件,定义您正在使用的路由... - Georg Engel
聚合和Git子模块并不能解决所有问题(特别是Git子模块)。 - jwinandy
3个回答

5
这是我所做的和已经完成的工作。我创建了一个多模块Maven项目,基本上保留了所有核心可重用代码。
然后对于我所有的其他网络项目(生成WAR的项目),我使用SBT、Gradle,甚至在一些情况下使用带有Maven插件的Ant。这些项目保留了自己的配置(如数据库主机和凭据)。
framework
   - pom.xml
   - db-module
     - pom.xml
     - src/main/resources # possible classpath loading config here
     - etc...
   - mail-module
     - pom.xml
     - etc...
   - service-module
     - pom.xml
     - etc...

对于其他的项目,只需依赖于框架即可。对于SBT项目(play 2.0),您可以设置本地maven仓库为其中一个解析器:https://github.com/harrah/xsbt/wiki/Getting-Started-Library-Dependencies

编辑说明: 框架pom.xml是父项目。您可以使邮件模块依赖于数据库模块,然后在单独的web应用程序项目中,您只需要依赖于邮件模块,就可以同时获得邮件模块和数据库模块。

许多人把Maven看作过时的工具,但它仍然是最好的多模块项目构建工具。

更多说明:


如果你想的话,是可以在多模块项目中有内部模块依赖的。Maven也会防止循环依赖的发生。我建议你查看我提供的Maven文档示例:http://www.sonatype.com/books/mvnex-book/reference/multimodule.html - Adam Gent
这实际上不是我正在寻找的解决方案。我的项目基于Maven,具有多模块结构。我的问题实际上是关于conf级别的,参考http://www.playframework.org/documentation/2.0/Configuration,但是该文档并没有提供清晰的解释。 - Edmondo
1
我在考虑删除我的回答,因为你已经修改了你的问题6次,而且我误解了你最初的帖子,所以我得到了-1分。如果你想让我保留它,请告诉我。 - Adam Gent
1
它仍然相关。谢谢你分享你的知识。 - Edmondo

2
我们正在使用子模块,如下所示(其中“core”是共享的子模块):
Build.scala
val coreModule = PlayProject(appName + "-core", "1.0", appDependencies, path = file("modules") / "core")

val main = PlayProject(appName + "-app", appVersion, appDependencies, mainLang = SCALA).settings(
  // Add your own project settings here      
).dependsOn(coreModule).aggregate(coreModule)

不幸的是,子模块必须存在于项目树下(无法使用“../core”作为路径)- 因此我们正在使用git子模块将共享模块添加到树中:

git submodule add git://git.example.com/modules.git modules

git submodule init

git submodule update

可能SVN externals、mercurial submodules等也可以完成这个任务。

1
我不需要一个核心玩项目,而是一个独立于sbt的模块,其中包含一个配置文件,我可以在我的主项目中导入。 - Edmondo
免责声明:我们未使用Play的数据层……你应该可以通过在你的application.conf中使用“include“core.conf””来包含一个持有共享配置的文件。这个文件从classpath读取,所以将其放入你的core-conf文件夹中也能让你共享配置。 - Georg Engel
子项目也可以是“常规”(非Play)项目:val foo = Project(id =“hello-foo”,base = file(“foo”))。只要core.conf在类路径上,您就可以将其包含在application.conf中。据我所知,在普通项目中进行的更改不会强制播放应用程序重新加载,因为更改不会自动检测到(但是从2.0.1到2.0.2发生了变化,如果不正确,请耐心等待)。 - Georg Engel

1

源代码中依赖于某个模块的位置,可以帮助你实现所需的构建:

import sbt._
import Keys._
import PlayProject._

object ApplicationBuild extends Build {

    val appName         = "test"
    val appVersion      = "1.0-SNAPSHOT"

    val appDependencies = Seq(
      // Add your project dependencies here,
    )

    lazy val main = PlayProject(appName, appVersion, appDependencies, mainLang = SCALA).settings(
      // Add your own project settings here      
    ).dependsOn(common)


    lazy val common = RootProject(file("../common")) 


}

您不能将一个play项目与另一个混合,因此您的配置应该在“dependencies”中。源依赖项的好处是它们在您的项目中实时存在(感谢SBT的递归)。如果您的依赖源发生更改,则主项目会在下一次编译时获得更改。

您可以在此处检查我的多模块play应用程序的完整结构:https://github.com/un-jon/play2MultiModule


1
一个RootProject和Project之间的区别是什么? - Edmondo
这只是声明“外部”依赖项的一种方式。它比Project更灵活。(请参见 https://github.com/harrah/xsbt/wiki/Full-Configuration(在“Project References”下))。 - jwinandy
我更加困惑了...为什么更灵活? - Edmondo
2
  1. 你不必在子目录中定义一个模块。
  2. 外部项目有它们自己的生命周期,例如它们的构建不必使用playPlugin。
- jwinandy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接