SBT - 根据任务有条件地设置 exportJars 设置

SBT - conditionally set exportJars setting based on task

我有一个混合服务器端 Scala / Scala.js 项目,构建为可运行的 jar。我正在使用 sbt-revolver 插件在更改任何文件时重新启动主 class,并使用 ~ fastOptJS 在更改客户端文件时重新编译 JS。

如果只有客户端文件发生更改,我不想重新启动主程序 class,因为这会使反馈周期变慢。我使用我定义的名为 "build" 的任务将罐子复制到我想要的位置(对于 Docker),如下所示:

exportJars := true
mainClass in appJVM := Some("myproject.Server")

packageOptions in (appJVM, Compile, packageBin) += ManifestAttributes( "Class-Path" -> externalDependencyClasspath.in(appJVM, Runtime).value.files.map { file => s"dependencies/${file.name}" }.mkString(" ") )

lazy val build = taskKey[Unit]("Ensures jars are in the right places for Docker")
build := {

  val packagedDir = new File(target.value, "packaged")
  IO.delete(packagedDir)
  val dependenciesDir = new File(target.value, "packaged/dependencies")
  dependenciesDir.mkdirs()

  val (_, artifactFile) = packagedArtifact.in(appJVM, Compile, packageBin).value
  Files.copy(artifactFile.toPath, new File(packagedDir, artifactFile.getName).toPath, COPY_ATTRIBUTES)

  externalDependencyClasspath.in(appJVM, Runtime, build).value.files.foreach { file =>
    Files.copy(file.toPath, new File(dependenciesDir, file.name).toPath, COPY_ATTRIBUTES)
  }
}

然而,这意味着当我使用 appJVM/reStart 它实际上运行 jar 文件,这反过来意味着为了更改客户端 JS,jar 文件必须重建并且服务器必须重新启动。

如果我设置 exportJars := false 然后 appJVM/reStart 从 classes 目录运行我的项目,所以只有 运行 fastOptJS 可以让我看到我的更改而无需重新启动服务器。

有没有办法根据我是否运行构建任务有条件地设置exportJars

看起来就像将设置 exportJars 移动到我的 build 任务中一样简单:

build := {
  exportJars := true
  ...
}

我的最终结论是,如果我完全删除 exportJars 设置,但让构建依赖于 packagedArtifact.in(appJVM, Compile, packageBin),那么我就两全其美了。 reStart 运行 来自 类 目录,因此可以即时更改资源,但我仍然有一个 jar 构建,我可以将其复制到正确的位置。

(这仍然让 internalDependencyClasspath 返回 类 目录而不是 jar - 除了通过不使用 internalDependencyClasspath 来解决它之外,我没有其他解决方案。)