如何为 appJS/appJVM 交叉构建项目运行 scala sbt-native-packager
Posted
技术标签:
【中文标题】如何为 appJS/appJVM 交叉构建项目运行 scala sbt-native-packager【英文标题】:how to run scala sbt-native-packager for a appJS/appJVM cross-build project 【发布时间】:2020-03-11 18:48:20 【问题描述】:sbt-native-packager 可以制作一个包含所有依赖项的 zip 文件和一个要运行的脚本_
$ sbt universal:packageBin
我有一个 scala Web 应用程序,使用交叉构建(appJS 用于前端,appJVM 用于后端)。
如何为 appJVM 运行此打包程序? 我试过如下,但它不接受命令:
$ sbt appJVM/universal:packageBin
这里是 build.sbt 项目,来自https://www.scala-js.org/doc/project/cross-build.html
...
lazy val foo = crossProject.in(file(".")).
settings(
name := "foo",
version := "0.1-SNAPSHOT"
).
jvmSettings(
// Add JVM-specific settings here
).
jsSettings(
// Add JS-specific settings here
)
lazy val fooJVM = foo.jvm
lazy val fooJS = foo.js
如何为 appJVM 运行此打包程序?
以及我如何包含sbt appJS/fullOptJS
生成的文件?
还有其他一些静态文件?
Ivan 回复更新
build.sbt:
import sbtcrossproject.CrossPlugin.autoImport.crossProject, CrossType
val sharedSettings = Seq(
scalaVersion := "2.12.8",
)
lazy val app =
crossProject(JSPlatform, JVMPlatform)
.in(file("."))
.settings(sharedSettings)
.jsSettings(
)
.jvmSettings(
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-http" % "10.1.9"
),
)
lazy val backend = project
.enablePlugins(UniversalPlugin)
.enablePlugins(JavaAppPackaging)
.dependsOn(app.jvm)
.settings(
mainClass in Compile := Some("com.example.EchoServer")
)
lazy val frontend = project
.enablePlugins(ScalaJSPlugin)
.dependsOn(app.js)
backend
.settings(
Seq(
resourceGenerators in Compile += Def.task
Seq(
(fullOptJS in Compile in frontend).value,
(fastOptJS in Compile in frontend).value
).map js =>
val resource = (resourceManaged in Compile).value / "public" / "assets" / js.data.name
IO.write(resource, IO.read(js.data))
resource
.taskValue
)
)
然后运行:
$ sbt backend/universal:packageBin
34: error: type mismatch;
found : Seq[sbt.Def.Setting[Seq[sbt.Task[Seq[java.io.File]]]]]
required: Int
Seq(
^
[error] Type error in expression
【问题讨论】:
【参考方案1】:我使用了以下结构。
定义一个需要为 JS 和 Scala 交叉编译的共享项目。
lazy val shared = CrossPlugin.autoImport
.crossProject(JSPlatform, JVMPlatform)
.crossType(CrossType.Pure)
.jvmSettings(???)
.jsSettings(???)
lazy val sharedJvm = shared.jvm
lazy val sharedJs = shared.js
添加包含 Main 类的项目。
lazy val backend = project
.enablePlugins(UniversalPlugin)
.enablePlugins(JavaAppPackaging)
.dependsOn(sharedJvm)
添加包含网页相关代码的web
项目。
lazy val web = project
.enablePlugins(ScalaJSPlugin)
.dependsOn(sharedJs)
最后,将 web
中编译成 JS 的资源附加到 backend
。
backend
.settings(
Seq(
resourceGenerators in Compile += Def.task
Seq(
(fullOptJS in Compile in web).value,
(fastOptJS in Compile in web).value
).map js =>
val resource = (resourceManaged in Compile).value / "public" / "assets" / js.data.name
IO.write(resource, IO.read(js.data))
resource
.taskValue
)
主类需要服务从public/assets
编译的 JS,如 sbt 中配置的那样,以及来自其类路径的任何其他 Web 资源。
【讨论】:
我已根据您的建议更新了问题,但仍然失败。再次查看问题。 谢谢!我已经用你的信息更新了这个问题。如果我删除resourceGenerators
,则运行sbt backend/universal:packageBin
可以工作。否则它会以error: type mismatch; found : Seq[sbt.Def.Setting[Seq[sbt.Task[Seq[java.io.File]]]]], required: Int
失败。我已经阅读了scala-sbt.org/1.x/docs/Howto-Generating-Files.html 上的文档,但我看不到如何在settings
部分中设置资源生成器。以上是关于如何为 appJS/appJVM 交叉构建项目运行 scala sbt-native-packager的主要内容,如果未能解决你的问题,请参考以下文章