scala 如何使用 SBT 和 IntelliJ IDEA 管理多个相互依赖的模块?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8763317/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to manage multiple interdependent modules with SBT and IntelliJ IDEA?
提问by David Soergel
I'm developing several modules with dependencies among them, and would like to work with them all together in one IDEA project. I'm using sbt-ideato generate IDEA projects from the sbt build definitions, which works great for individual projects. In the multiple-module case, however, the things I've tried so far don't quite work:
我正在开发几个相互依赖的模块,并希望在一个 IDEA 项目中与它们一起工作。我正在使用sbt-idea从 sbt 构建定义生成 IDEA 项目,这对单个项目非常有用。然而,在多模块的情况下,到目前为止我尝试过的事情并不完全有效:
Use sbt-idea to generate an IDEA .iml file for each module independently; then create a master IDEA project from scratch an add those modules to it. This makes the module sources all editable in the same window, but the dependencies among them are not tracked (so trying to navigate from some source within the fooproject to something in bartakes me to the imported library version of bar, not the local sources).
使用sbt-idea为每个模块独立生成IDEA .iml文件;然后从头开始创建一个主 IDEA 项目并将这些模块添加到其中。这使得模块来源所有可编辑在同一窗口,但它们之间的依赖关系是不被跟踪(因此从内某些源试图导航FOO项目,在一些酒吧带我到的进口库版本吧,而不是本地资源)。
Use sbt multi-project builds(aka subprojects), where the parent project's Build.scala contains things like:
使用 sbt multi-project builds(aka subprojects),其中父项目的 Build.scala 包含以下内容:
lazy val foo = Project(id = "foo", base = file("foo"))
lazy val bar = Project(id = "bar", base = file("bar")) dependsOn(foo)
This almost works, in that sbt-idea generates a master IDEA project with the dependencies among the subprojects tracked. There are however two caveats:
这几乎有效,因为 sbt-idea 生成了一个主 IDEA 项目,并跟踪了子项目之间的依赖关系。不过有两点需要注意:
- It seems to be an sbt restriction that the subprojects must live in subdirectories of the master project (i.e.,
file("../foo")is not allowed). This is not really what I want (what if a module--such as a "utils" or "commons" package--is used in two different master projects?) but I can live with it. - One of my subprojects has its own subprojects; I'm not sure whether sbt itself deals with these nested projects correctly, but in any case they are ignored by sbt-idea. Obviously I need nested subprojects to be included recursively in the master project.
- 子项目必须位于主项目的子目录中似乎是 sbt 限制(即
file("../foo")不允许)。这并不是我真正想要的(如果一个模块——比如“utils”或“commons”包——被用在两个不同的主项目中怎么办?)但我可以忍受它。 - 我的一个子项目有自己的子项目;我不确定 sbt 本身是否正确处理这些嵌套项目,但无论如何它们都会被 sbt-idea 忽略。显然,我需要将嵌套子项目递归地包含在主项目中。
To summarize: I'd like to collect modules which may already have subprojectsinto one big IDEA project with tracked dependencies for convenient editing. How can I do it? Thanks!
总结一下:我想将可能已经有子项目的模块收集到一个带有跟踪依赖项的大型 IDEA 项目中,以便于编辑。我该怎么做?谢谢!
回答by Edmondo1984
The approach with multi-project build is the correct one. You can have a nested tree of subprojects of arbitrary length, but you cannot have a module belonging to multiple parent projects. This makes absolutely sense, and in Maven happens the same.
多项目构建的方法是正确的。您可以拥有任意长度的子项目的嵌套树,但不能拥有属于多个父项目的模块。这绝对有道理,在 Maven 中也是如此。
The reason is that it would be hard to have the same module into multiple projects and keep the sources synchronized. A normal workflow is the following:
原因是很难将相同的模块放入多个项目并保持源同步。正常的工作流程如下:
- You have a project which the module belongs to, where you modify the module source.
- You publish the module into your local repository
- In other projects where you need the module, you declare it as a libraryDependency
- 您有一个模块所属的项目,您可以在其中修改模块源。
- 您将模块发布到本地存储库中
- 在需要该模块的其他项目中,将其声明为 libraryDependency
If you want to load a module which does not belong to the current project inside Idea, this is however feasible as you can add this as an external module to the workspace:
如果要加载不属于 Idea 中当前项目的模块,这是可行的,因为您可以将其作为外部模块添加到工作区:
- SBT-IDEA generates the .iml files for your project and you import them in the workspace
- You can add other.iml of other projects to the workspace
- If you modify external SBT modules that you have manually added to the workspace, you should republish them to get the changes visibile on the "main" project, which sees those external modules are a "libraryDependency"
- SBT-IDEA 为您的项目生成 .iml 文件并将它们导入工作区
- 可以将其他项目的 other.iml 添加到工作区
- 如果您修改手动添加到工作区的外部 SBT 模块,您应该重新发布它们以在“主”项目上看到更改,该项目看到这些外部模块是“libraryDependency”
回答by user2829759
It seems to be an sbt restriction that the subprojects must live in subdirectories of the master project (i.e., file("../foo") is not allowed). This is not really what I want (what if a module--such as a "utils" or "commons" package--is used in two different master projects?) but I can live with it.
子项目必须位于主项目的子目录中似乎是 sbt 限制(即不允许 file("../foo"))。这并不是我真正想要的(如果一个模块——例如“utils”或“commons”包——在两个不同的主项目中使用会怎样?)但我可以接受它。
With sbt 13.5 and intellij 13.x, you can specify inter-project dependency with relative path, using a Build.scala. Let's say you have two projects, a core project commonsand another project foo, both living in a common directory code/
使用 sbt 13.5 和 intellij 13.x,您可以使用 Build.scala 指定具有相对路径的项目间依赖项。假设您有两个项目,一个核心项目commons和另一个项目foo,都生活在一个公共目录code/
- create Build.scala under code/foo/project/
put this code snippet insde 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) }Generate your IntelliJ project via sbt by
sbt gen-idea
- 在 code/foo/project/ 下创建 Build.scala
将此代码片段放入 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) }通过 sbt 生成您的 IntelliJ 项目
sbt gen-idea

