如何使用SBT将多模块项目中的BL模块发布为库?
可行,这在Scala生态里是很常规的做法
你完全可以把业务逻辑(BL)和CLI放在同一个项目里,只发布BL模块到仓库供JVM和ScalaJS应用使用。下面是具体的实现步骤,以sbt构建工具为例(Scala项目的主流选择):
1. 规划项目结构
先搭建多模块的项目目录,把BL和CLI拆成独立子模块:
your-project/ ├── build.sbt ├── bl/ # 跨平台的业务逻辑模块 │ ├── src/ │ │ ├── main/scala/ │ │ └── test/scala/ └── cli/ # 仅JVM的CLI模块 ├── src/ │ ├── main/scala/ │ └── test/scala/
2. 配置sbt多模块与跨平台支持
在根目录的build.sbt里定义跨平台的BL模块,以及依赖它的CLI模块:
// 先添加ScalaJS插件(通常放在project/plugins.sbt里) // addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.15.0") lazy val root = (project in file(".")) .aggregate(blJVM, blJS, cli) .settings( publish / skip := true // 根项目不需要发布 ) // 定义跨JVM/ScalaJS的BL模块 lazy val bl = crossProject(JVMPlatform, JSPlatform) .crossType(CrossType.Pure) // 纯Scala代码,无平台专属逻辑 .in(file("bl")) .settings( name := "your-bl-library", organization := "com.yourcompany", version := "0.1.0", scalaVersion := "2.13.12", // 测试依赖示例 libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.15" % Test ) lazy val blJVM = bl.jvm // BL的JVM版本 lazy val blJS = bl.js // BL的ScalaJS版本 // CLI模块,仅依赖BL的JVM版本 lazy val cli = (project in file("cli")) .dependsOn(blJVM) .settings( name := "your-cli", scalaVersion := "2.13.12", publish / skip := true, // CLI模块不发布 mainClass := Some("com.yourcompany.cli.Main") // 指定CLI入口类 )
CrossType.Pure适用于BL无平台特定代码的场景;如果有JVM/JS专属逻辑,改用CrossType.Full,此时需要在bl/jvm/src和bl/js/src分别存放对应平台的代码。- 通过
publish / skip := true控制只发布BL的两个平台版本,根项目和CLI都跳过发布。
3. 发布BL模块
直接针对BL的JVM和JS版本执行发布命令即可:
sbt blJVM/publish blJS/publish
如果要发布到Maven Central这类公共仓库,还需要在BL模块的settings里配置publishTo、签名等信息,具体可参考sbt官方的发布文档。
其他项目引入BL时,JVM端用双百分号%%,ScalaJS端用三分号%%%:
- JVM依赖:
"com.yourcompany" %% "your-bl-library" % "0.1.0" - ScalaJS依赖:
"com.yourcompany" %%% "your-bl-library" % "0.1.0"
4. 注意事项
- 确保BL模块不依赖CLI模块,避免循环依赖。
- 平台专属代码要放在对应模块的源目录下,不要混在公共代码里。
- 测试时可以分别运行
blJVM/test和blJS/test,确保两个平台的逻辑都正常。
内容的提问来源于stack exchange,提问作者bwbecker
相关产品推荐
相关产品推荐

