Three.js 的新 Scala.js 门面 -> "Cannot find module "THREE""

New Scala.js facade for Three.js -> "Cannot find module "THREE""

作为 https://github.com/antonkulaga/threejs-facade is heavily outdated I tried an approach like: https://github.com/Katrix-/threejs-facade 并想为新的 three.js 库创建外观。

我绝不是 JS 专家,我也不是 Scala.js 专家,所以很可能我在做一些非常愚蠢的事情。

在另一个问题之后我正在使用这个 sbt-scalajs-bundlersbt-web-scalajs-bundler

我的 build.sbt 看起来像这样:

lazy val client = (project in file("modules/client"))
  .enablePlugins(ScalaJSBundlerPlugin, ScalaJSWeb) // ScalaJSBundlerPlugin automatically enables ScalaJSPlugin
  .settings(generalSettings: _*)
  .settings(
    name := "client"
    //, scalaJSModuleKind := ModuleKind.CommonJSModule // ScalaJSBundlerPlugin implicitly sets moduleKind to CommonJSModule enables ScalaJSPlugin
   ,jsDependencies += ProvidedJS / "three.min.js"
  )

lazy val server = (project in file("modules/server"))
  .enablePlugins(PlayScala, WebScalaJSBundlerPlugin)
  .settings(generalSettings: _*)
  .settings(
    name := "server"
    ,scalaJSProjects := Seq(client)
    ,pipelineStages in Assets := Seq(scalaJSPipeline)
    //,pipelineStages := Seq(digest, gzip)
    ,compile in Compile := ((compile in Compile) dependsOn scalaJSPipeline).value
  )

three.min.js 在我的 client 项目的资源文件夹中。

Facade 的一部分是例如

@js.native
@JSImport("THREE", "Scene")
class Scene extends Object3D {

我想这样使用它:val scene = new Scene。在 scala.js 方面,这实际上编译得很好,但是当我 运行 它时,我得到:

Error: Cannot find module "THREE"

在浏览器中,我想知道为什么。毕竟three.min.js里面是这样叫的

现在我也尝试从服务器端提供和提供 three.min.js 文件,因为我认为它可能只是在 运行 时丢失了,但不,这似乎并没有是原因。

所以现在我想知道我在这里做错了什么?

只是为了澄清:如果我不导出 Facade 的任何用法,其余的转译 js 工作正常!

如 Scala.js 文档的 this part 中所述,@JSImport 被编译器解释为 JavaScript 模块导入。

当您使用 CommonJSModule 模块种类时(当您启用 ScalaJSBundlerPlugin 时就是这种情况),此导入将转换为以下 CommonJS 导入:

var Scene = require("THREE").Scene;

这个注解只告诉你的 Scala 代码将如何与 JS 世界接口,但它没有告诉你如何解决 提供 THREE 模块的依赖关系.


使用 scalajs-bundler,您可以通过将以下设置添加到 client 项目来定义 how to resolve JS dependencies from the NPM registry

npmDependencies += "three" -> "0.84.0"

(请注意,您不能使用 jsDependencies 来解析这些带有 @JSImport 的模块)

此外,请注意使用 three.js 的正确 CommonJS 导入是 "three" 而不是 "THREE",因此您的 @JSImport 注释应如下所示:

@JSImport("three", "Scene")

或者,如果您不想从 NPM 注册表中解析您的依赖项,您可以将 CommonJS 模块作为资源文件提供。直接放在src/main/resources/Scene.js下,在@JSImport中引用如下:

@JSImport("./Scene", "Scene")

您可以看到一个工作示例 here