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


82

我正在开发几个相互依赖的模块,并希望在一个IDEA项目中一起使用它们。我正在使用sbt-idea从sbt构建定义中生成IDEA项目,这对于单个项目非常有用。但是,在多模块的情况下,到目前为止,我已经尝试了一些事情:

使用sbt-idea分别为每个模块生成一个IDEA .iml文件;然后从头开始创建一个主IDEA项目,并向其中添加这些模块。这使得模块来源所有可编辑在同一窗口,但它们之间的依赖关系是不被跟踪(因此从内某些源试图导航FOO项目,在一些酒吧带我到的进口库版本,而不是本地资源)。

使用sbt多项目构建(又称子项目),其中父项目的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")不允许)是sbt的限制。这不是我真正想要的(如果在两个不同的主项目中使用模块(例如“ utils”或“ commons”包),该怎么办?)但我可以接受。
  2. 我的一个子项目有自己的子项目。我不确定sbt本身是否正确处理了这些嵌套项目,但是无论如何它们都被sbt-idea忽略。显然,我需要将嵌套子项目递归地包含在主项目中。

总结一下:我想将可能已经有子项目的模块收集到一个具有跟踪依赖项的大型IDEA项目中,以方便进行编辑。我该怎么做?谢谢!


2
尝试建立一个将其他项目链接为外部项目引用的元项目(github.com/harrah/xsbt/wiki/Full-Configuration)。我自己没有使用sbt-idea尝试过此操作,因此这是评论而不是答案。
retronym 2012年

感谢您的想法-但可悲的是sbt-idea完全忽略了外部引用。
David Soergel


太酷了,所以我从最新的git来源安装了svn-idea来进行这些更改,然后清理项目并再次运行sbt-idea。有一些我不完全理解的怪异的依赖关系解决问题,但是最终我以一个可行的项目结束了!我确实必须在IDEA中为子子项目手动设置源目录。回想起来,我不确定我最初使用股票sbt-idea 11.1不能做到这一点。无论如何,谢谢-我想暂时不要再stop牛了。
David Soergel

在写完最后一条评论后,我发现我根本没有一个有效的项目(同样,子子项目很麻烦)。因此,我只是将它们分为一流的项目,所以我的主项目现在只有一个子项目级别。当然,我只能这样做,因为这是我自己所有的代码。
David Soergel 2012年

Answers:


7

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

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

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

如果要在Idea中加载不属于当前项目的模块,那么这是可行的,因为您可以将其作为外部模块添加到工作空间中:

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

感谢您的输入。但是,问题在于不是“您可以拥有任意长度的子项目的嵌套树”。我同意这应该与sbt一起使用,但是sbt-idea显然不在生成的IDEA项目文件中包括子子项目。
大卫·索格尔

此限制是否来自想法?
Edmondo1984年

不,我当然已经将IDEA项目层次结构深了几个层次。
David Soergel

7

子项目必须位于主项目的子目录中似乎是一个sbt限制(即,不允许file(“ ../ foo”))。这不是我真正想要的(如果在两个不同的主项目中使用模块(例如“ utils”或“ commons”包),该怎么办?)但我可以接受。

使用sbt 13.5和intellij 13.x,您可以使用Build.scala使用相对路径指定项目间的依赖关系。假设您有两个项目,一个核心项目Commons和另一个项目foo,它们都位于一个公共目录代码/中

  1. 在代码/ foo / project /下创建Build.scala
  2. 将此代码段放入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)
    }
    
  3. 通过sbt生成您的IntelliJ项目 sbt gen-idea


这将允许通过从“ foo”链接来编辑“ commons”源吗?
Tjunkie 2015年

是的,它允许。它适用于我的sbt 0.13.7和intellij 14.0.3安装
user2829759
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.