【问题标题】:Using DependsOn between two ScalaJS SBT projects在两个 ScalaJS SBT 项目之间使用 DependsOn
【发布时间】:2016-11-07 23:29:12
【问题描述】:

(前面的问题很长。简化的 tl;底部的博士)。

我有两个使用 SBT 构建的 ScalaJS 项目——“myapp”和“mylib”,位于以下目录结构中

root/build.sbt

root/myapp/build.sbt
root/myapp/jvm/
root/myapp/js/
root/myapp/shared/

root/mylib/build.sbt
root/mylib/jvm
root/mylib/js
root/mylib/shared

lib 导出一个名为“com.example:mylib:0.1”的工件,用作myapp 的 libraryDependency。

myapp 和 mylib 位于不同的存储库中,包含它们自己的构建文件,并且应该能够完全独立地构建(即它们必须包含自己的单独构建配置)。

在生产中,它们将单独构建,mylib 首先作为 maven 工件发布,然后单独构建 myapp

然而,在开发过程中,我希望能够将它们合并到父 SBT 项目中,以便可以并行开发两者,而无需在每次更改后使用 publishLocal

在传统(非 scalajs)项目中,这将非常容易

$ROOT/build.sbt:

lazy val mylib = project
lazy val myapp = project.dependsOn(mylib)

然而在 ScalaJS 中,我们实际上在每个模块中都有两个项目 - appJVMappJSlibJVMlibJS。因此,上面的配置只找到聚合根项目,并没有正确地将dependsOn配置应用到实际的JVM和JS项目中。

(即 myapp 和 mylib build.sbt 分别包含两个项目和一个聚合根项目)

理想情况下,我希望能够执行以下操作

lazy val mylibJVM = project
lazy val myappJVM = project.dependsOn(mylibJVM)

lazy val mylibJS = project
lazy val myappJS = project.dependsOn(myappJS)

不幸的是,这只是在根目录中创建新项目,而不是自己导入子项目。

我也尝试过各种路径组合(比如)

lazy val mylibJVM = project.in(file("mylib/jvm"))

但这并没有在mylib的build.sbt文件中看到配置

最终我一直遇到同样的问题 - 将现有的多项目 SBT 项目导入父 sbt 文件时,它会导入根项目,但似乎没有提供从现有多模块导入子项目的方法SBT 文件,让我可以向其中添加 dependsOn 配置。

tl;博士

如果我有

  • root/mylib/build.sbt 定义了多个项目并
  • root/myapp/build.sbt 定义了多个项目

是否可以将单个子项目导入root/build.sbt 而不是子模块中的根项目?

即我可以有两层多项目构建吗?

【问题讨论】:

  • 我的 scalajs 和 sbt 知识已经有一年了,我不知道 jvm 和 js 之间的拆分是什么时候为 scalajs 项目引入的,甚至不知道这意味着什么,但我的插件版本是 0.6.4 ,我会这样做: 1)创建一个依赖于 lib 的 fastOptJs 任务的复印机任务,并将输出从 lib 复制到应用程序 2)使应用程序的 fastOptJs 任务依赖于此 如果这部分有帮助,在这种情况下我可以尝试帮助更多。
  • 看看here

标签: scala sbt scala.js


【解决方案1】:

在花费大量时间挖掘 SBT 源代码后,我设法找到了解决方案。这不干净,但它有效。 (对于奖励积分,它可以正确导入 IntelliJ)。

// Add this function to your root build.sbt file. 
// It can be used to define a dependency between any
// `ProjectRef` without needing a full project definition.
def addDep(from:String, to:String) = {
  buildDependencies in Global <<= (
  buildDependencies in Global, 
  thisProjectRef in from, 
  thisProjectRef in to) { 
    (deps, fromref, toref) => 
      deps.addClasspath(fromref, ResolvedClasspathDependency(toref, None))
  }
}

// `project` will import the `build.sbt` file
// in the subdirectory of the same name as the `lazy val`
// (performed by an SBT macro). i.e. `./mylib/build.sbt`
// 
// This won't reference the actual subprojects directly, 
// will but import them into the namespace such that they 
// can be referenced as "ProjectRefs", which are implicitly
// converted to from strings.
// 
// We then aggregate the JVM and JS ScalaJS projects 
// into the new root project we've defined. (Which unfortunately
// won't inherit anything from the child build.sbt)

lazy val mylib = project.aggregate("mylibJVM","mylibJS")
lazy val myapp = project.aggregate("myappJVM","myappJS")

// Define a root project to aggregate everything
lazy val root = project.in(file(".")).aggregate(mylib,myapp)


// We now call our custom function to define a ClassPath dependency
// between `myapp` -> `mylib` for both JVM and JS subprojects.
// In particular, this will correctly find exported artifacts
// so that `myapp` can refer to `mylib` in libraryDependencies
// without needing to use `publishLocal`. 
addDep("myappJVM", "mylibJVM")
addDep("myappJS","mylibJS")

【讨论】:

    猜你喜欢
    • 2019-07-28
    • 2015-10-08
    • 1970-01-01
    • 2014-04-28
    • 2017-06-11
    • 2013-11-19
    • 2018-11-28
    • 1970-01-01
    • 2013-11-18
    相关资源
    最近更新 更多