You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Mill发布含平台特定代码的JVM/JS跨平台库遇类型冲突问题

问题核心分析

报错的本质是类型不匹配:xpShared.jvm和xpShared.js因混入XP_Publish(继承自PublishModule),其moduleDeps要求依赖的模块必须也是PublishModule类型;但你定义的xpJVM、xpJS只是普通的ScalaModule子类,未实现PublishModule接口,导致编译器类型校验失败。


解决方案(贴合你偏好的依赖方式)

方案1:让平台特定模块兼容PublishModule类型

直接修改xpJVM和xpJS,让它们也混入XP_Publish(或直接继承PublishModule),同时修改artifactName避免发布冲突:

// JVM-specific stuff
object xpJVM extends AppScalaModule with XP_Publish {
  override def artifactName = "xp-jvm"
}
// JS-specific stuff
object xpJS extends AppScalaJSModule with XP_Publish {
  override def artifactName = "xp-js"
}

修改后xpShared.jvm/js的moduleDeps就能正常依赖这两个模块,类型匹配问题解决。

方案2:显式放宽moduleDeps的类型约束

如果不想让平台特定模块成为可发布模块,可以显式指定moduleDeps的类型为父类ScalaModule,绕过PublishModule的强制类型要求:

object jvm extends SharedModule with XP_Publish {
  // 显式指定类型为ScalaModule,兼容普通模块依赖
  override def moduleDeps: Seq[ScalaModule] = Seq(xpJVM)
  object test extends ScalaTests {
    def ivyDeps = Agg(ivy"com.lihaoyi::utest::0.8.5")
    def testFramework = "utest.runner.Framework"
  }
}

object js extends SharedModule with AppScalaJSModule with XP_Publish {
  override def moduleDeps: Seq[ScalaModule] = Seq(xpJS)
  object test extends ScalaTests with ScalaJSTests {
    def ivyDeps = Agg(ivy"com.lihaoyi::utest::0.8.5")
    def testFramework = "utest.runner.Framework"
  }
}

对你提出方案的评价

  1. 关于CrossScalaModule:完全没必要采用。CrossScalaModule是用于多Scala版本编译的工具,和JVM/JS跨平台无关,反而会增加不必要的构建复杂度,直接排除该方案即可。
  2. 关于重写sources纳入平台代码:该方案可行,但会模糊模块边界,不利于后续维护(尤其是平台代码量增加后)。如果平台特定代码极少,可临时用这种方式;但长期来看,依赖方式的模块化程度更高,更推荐采用前面的方案。

内容的提问来源于stack exchange,提问作者bwbecker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 13:26:18