如何使用SBT和IntelliJ IDEA管理多个相互依赖的模块?

时间:2012-01-06 19:27:22

标签: scala intellij-idea sbt sbt-idea

我正在开发几个具有依赖关系的模块,并希望在一个IDEA项目中一起使用它们。我正在使用sbt-idea从sbt构建定义生成IDEA项目,这对于单个项目非常有用。然而,在多模块的情况下,我到目前为止所尝试的事情并不完全有效:

使用sbt-idea独立生成每个模块的IDEA .iml文件;然后从头开始创建一个主IDEA项目,并将这些模块添加到它。这使得模块源可以在同一个窗口中编辑,但是不跟踪它们之间的依赖关系(因此尝试从 foo 项目中的某些源导航到 bar 中的某些内容将我带到 bar 的导入库版本,而不是本地源。)

使用sbt multi-project builds(也称为子项目),其中父项目的Build.scala包含以下内容:

lazy val foo = Project(id = "foo", base = file("foo"))
lazy val bar = Project(id = "bar", base = file("bar")) dependsOn(foo)

这几乎可行,因为sbt-idea会生成一个主IDEA项目,其中跟踪子项目之间的依赖关系。然而,有两个警告:

  1. 这似乎是一个限制,子项目必须存在于主项目的子目录中(即,file("../foo")是不允许的)。这不是我想要的(如果一个模块 - 比如“utils”或“commons”包 - 在两个不同的主项目中使用会怎么样?)但是我可以忍受它。
  2. 我的一个子项目有自己的子项目;我不确定sbt本身是否正确处理这些嵌套项目,但无论如何它们都会被sbt-idea忽略。显然,我需要在主项目中递归地包含嵌套的子项目。
  3. 总结一下:我想将一些可能已经有子项目的模块收集到一个具有跟踪依赖关系的大型IDEA项目中,以方便编辑。我该怎么做?谢谢!

2 个答案:

答案 0 :(得分:7)

多项目构建的方法是正确的。您可以拥有任意长度的子项目的嵌套树,但您不能拥有属于多个父项目的模块。这绝对有意义,并且在Maven中也是如此。

原因是很难将同一模块放入多个项目并保持源同步。正常的工作流程如下:

  • 您有一个模块所属的项目,您可以在其中修改模块源。
  • 您将模块发布到本地存储库
  • 在您需要该模块的其他项目中,将其声明为libraryDependency

如果你想在Idea中加载一个不属于当前项目的模块,那么这是可行的,因为你可以将它作为外部模块添加到工作区:

  • SBT-IDEA为您的项目生成.iml文件,然后在工作区中导入它们
  • 您可以将其他项目的other.iml添加到工作区
  • 如果您修改已手动添加到工作区的外部SBT模块,则应重新发布它们以在“主”项目上获取可更改的内容,该项目将看到这些外部模块是“libraryDependency”

答案 1 :(得分:7)

  

子项目必须存在于主项目的子目录中(即,不允许使用文件(" ../ foo"))似乎是一种限制。这不是我想要的(如果一个模块 - 例如" utils"或者#34; commons"包 - 在两个不同的主项目中使用了怎么办?)但我可以活下去用它。

使用sbt 13.5和intellij 13.x,您可以使用 Build.scala 指定具有相对路径的项目间依赖项。 假设您有两个项目,一个核心项目 commons ,另一个项目 foo ,两个项目都位于一个公共目录 code / < / p>

  1. 在code / foo / project /
  2. 下创建Build.scala
  3. 将此代码段放入Build.scala

    object ProjectDependencies {
        val commons = RootProject(file("../commons"))
    }
    
    object ProjectBuild extends Build {
        import ProjectDependencies._
    
        lazy val root = Project(id = "foo", base = file(".")).dependsOn(commons)
    }
    
  4. 通过sbt gen-idea

  5. 的sbt生成您的IntelliJ项目