Scala.js 编译目标

Scala.js compilation destination

我正在开发一个 Scala.js 交叉项目,其中 jvm 文件夹代表我的服务器应用程序,js 代表我的 scala.js 代码。

每当我通过 sbt crossJS/fastOptJS 编译我的 scala.js 代码时,编译后的 JS 最终会在 ./js/target/scala-2.11/web-fastopt.js.

我需要在 jvm 文件夹中的服务器项目的资源中访问这个已编译的 JS 文件,这样我就可以通过我的 Web 应用程序为它提供服务。我想我必须用 artifactPath 做点什么,但到目前为止我似乎无法从我的实验中得到任何结果。

您可以配置 Scala.js SBT 插件以在您选择的文件夹中输出 JavaScript 文件。例如像这样:

// configure a specific directory for scalajs output
val scalajsOutputDir = Def.settingKey[File]("directory for javascript files output by scalajs")

// make all JS builds use the output dir defined later
lazy val js2jvmSettings = Seq(fastOptJS, fullOptJS, packageJSDependencies) map { packageJSKey =>
  crossTarget in(js, Compile, packageJSKey) := scalajsOutputDir.value
}
// instantiate the JVM project for SBT with some additional settings
lazy val jvm: Project = sharedProject.jvm.settings(js2jvmSettings: _*).settings(
  // scala.js output is directed under "web/js" dir in the jvm project
  scalajsOutputDir := (classDirectory in Compile).value / "web" / "js",

这还将在同一文件夹中存储 -jsdeps.js 和 .js.map 文件,以备您要在网络应用程序中使用它们。

有关更完整的示例,请查看 this tutorial,它解决了创建更复杂 Scala.js 应用程序的许多其他问题。

您可以简单地将 fastOptJS 任务(或 fullOptJS 任务)的 artifactPath 设置为您的 JVM 项目的(托管)资源目录:

// In the JS project's settings
artifactPath in fastOptJS in Compile :=
  (resourceManaged in jvm in Compile).value /
    ((moduleName in fastOptJS).value + "-fastopt.js"))

这将把它放在目录中,如果你 运行 fastOptJS 任务。但是,它不会包含在 sbt 的 resources 任务中,如果您启动服务器,它也不会自动触发。因此:

// In the JVM project's settings
resources in Compile += (fastOptJS in js).value.data

一些注意事项:

  • 仅当您的网络服务器仅提供特定目录时才需要第一步。否则第二个就足够了,因为这已经将文件添加到资源中;它所在的位置是次要的。
  • 设置crossTarget,正如@ochrons的回答一样,也会输出资源目录中的所有.class.sjsir文件。
  • 查看 Vincent Munier 的 sbt-play-scalajs 开箱即用的 sbt-web / Scala.js 集成(它采用稍微不同的方法:它从 js 项目,而不是直接放在 JVM 项目中。如果你有多个 JVM 项目,这很有用。