Play Framework 前端 JS 使用 Scala.js 外部依赖项

Play Framework frontend JS using Scala.js external dependencies

我正在尝试使用 ScalaJS 在公共库和我的游戏框架 Web 项目之间共享一些 Scala 代码。

我在单独的构建中使用 ScalaJS 创建了共享项目(不同的文件夹,不同的 build.sbt),包括使用 uTest 的单元测试,一切似乎都按预期工作。我交叉编译库代码以分离目标(shared_jvm 和 shared_js)并使用 SBT 的 publishLocal 命令。此时一切正常。

我使用以下代码在 web_js 文件夹中为我的特定 Web 应用程序 ScalaJS 代码在我的播放框架 Web 应用程序中创建了一个单独的项目:

lazy val web_js = (project in file("web_js")).settings(
  scalaVersion := "2.11.1",
  persistLauncher := true,
  persistLauncher in Test := false,
  unmanagedSourceDirectories in Compile := Seq((scalaSource in Compile).value),
  libraryDependencies ++= Seq(
    "org.scala-js" %%% "scalajs-dom" % "0.8.0",
    "be.doeraene" %%% "scalajs-jquery" % "0.8.0",
    "org.myorg" %%% "shared-js" % "0.1-SNAPSHOT"
  )).
  enablePlugins(ScalaJSPlugin, ScalaJSPlay)

库已由 SBT 毫无问题地解决。我可以编译并且没有错误,并且可以在我的代码中引用共享库。

为了使用我的共享 JS 代码,我扩展了 JSApp 并在我的共享库中调用一个对象,如下所示:

//Index.scala
import org.myorg.shared.SharedObject

object Index extends JSApp {
  def main(): Unit = {
    SharedObject.printSomething()
  }
}

但是,当我加载浏览器后调用它时,我收到与共享库中的对象相关的未定义错误:

Uncaught TypeError: undefined is not a function

如何将依赖的 ScalaJS 库加载到我的 Play Framework 项目的页面中?

其他说明:

我无法在 chrome 的 "sources" 调试器视图中看到我的共享库代码。我只能看到上面粘贴的 Index.scala 代码片段。这让我相信我引用的共享库实际上并没有被浏览器加载,但我不确定它是否是这样工作的。

顺便说一下,我已经看到了 play-with-scalajs-example 项目,我正在使用它来加载上面使用此代码段的 Index.scala 入口点:

@playscalajs.html.scripts("/assets", projectName = "web_js")

但是我用它来加载依赖库没有任何成功。

我想我只是误解了 javascript 错误 and/or 有段时间没有更新生成的 javascript。

事实证明我依赖于未加载的外部 javascript 资源 (moment.js)。当我通过将脚本标记插入页面手动加载它时:

<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/moment.min.js"></script>

它按预期工作并调用了我的共享库。这很奇怪,因为我不记得在生成的 fastopt.js 脚本中看到过我的代码,但我一定是错过了它,或者之前我的盒子上有一些配置问题。

我不确定为什么我的嵌入式 moment.js 脚本不起作用,因为它是我的一个依赖项中资源的一部分,并且我已将它包含在 jsDependencies 设置中,如下所示:

jsDependencies ++= Seq(
    "org.myorg" %%% "momentjs" % "0.1-SNAPSHOT" / "moment.js"
)

但我想这是一个新问题 post 如果我无法弄明白的话。