如何让IntelliJ识别sbt中spec模块对util模块的自定义依赖配置
问题
我在一个包含约50个子模块的大型项目中,想要创建一个spec(实际项目中叫myspec)模块作为项目的标准测试模块。这个模块的Compile配置需要依赖util模块的Compile范围,这样就能基于项目自定义工具类实现匹配器等通用测试逻辑。
我试过多种sbt配置:
- 最初用
dependsOn导致项目定义循环引用 - 改用
LocalProject还是存在循环依赖问题 - 最后通过
exportedProducts把util的Compile产物加入spec的Compile类路径,解决了sbt编译运行的问题,但IntelliJ无法识别spec对util的依赖,每次重新导入sbt定义都得手动调整项目结构。
请问怎么让IntelliJ自动识别这个依赖配置?
示例代码
util模块的Constants.scala
package com.example object Constants { val Foobar = "From util/Compile/Constants" }
spec模块的BaseSpec.scala
package com.example.spec trait BaseSpec { def fromBase: String = s"base include ${com.example.Constants.Foobar}" }
util测试模块的ConstantSpec.scala
package com.example object ConstantSpec extends App with com.example.spec.BaseSpec { println(s"test run: ${fromBase}") }
当前使用的sbt配置
lazy val util = (project in file("util")) .dependsOn(spec % Test) lazy val spec = (project in file("spec")) .settings( Compile / managedClasspath ++= (LocalProject("util") / Compile / exportedProducts).value )
解决方案
你之前手动用exportedProducts修改类路径的方式,IntelliJ的sbt导入插件不怎么认。其实你遇到的不是真循环依赖——util是在Test配置下依赖spec,而spec是在Compile配置下依赖util的Compile产物,二者配置范围不同,完全可以用sbt标准的dependsOn加配置限定来声明,这样IntelliJ就能自动识别依赖关系。
修改后的sbt配置如下:
lazy val util = (project in file("util")) // util的Test配置依赖spec的Compile产物 .dependsOn(spec % "test->compile") lazy val spec = (project in file("spec")) // spec的Compile配置依赖util的Compile产物 .dependsOn(util % "compile->compile")
这里的配置语法说明:
"test->compile":当前项目的Test配置,依赖目标项目的Compile配置产物"compile->compile":当前项目的Compile配置,依赖目标项目的Compile配置产物
这种方式既解决了循环依赖问题(编译顺序是先编译util的Compile,再编译spec的Compile,最后编译util的Test),又能让IntelliJ正确识别模块依赖,不用再手动调整项目结构。
内容的提问来源于stack exchange,提问作者Isammoc
相关产品推荐
相关产品推荐

