As https://github.com/antonkulaga/threejs-facade is heavily outdated I tried an approach like: https://github.com/Katrix-/threejs-facade and would like to create a facade for the new three.js
library.
I am by no means a JS
expert, nor am I a Scala.js
expert, so odds are I am doing something really dumb.
After another question I am using this sbt-scalajs-bundler
and sbt-web-scalajs-bundler
My build.sbt
looks like this:
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
is in the resources-folder of my client
project.
One part of the Facade is e.g.
@js.native
@JSImport("THREE", "Scene")
class Scene extends Object3D {
and I want to use it like this: val scene = new Scene
. On scala.js
side this actually compiles just fine, but when I run it I get:
Error: Cannot find module "THREE"
in the browser and I wonder why. It's called like this in three.min.js
after all.
Now I tried providing and serving the three.min.js
file from the server side as well, because I thought that maybe it was just missing at runtime, but no, that does not seem to be the cause.
So now I wonder what am I doing wrong here?
Just to clarify: Rest of transpiled js
works just fine, if I do not export any usage of the Facade!
As explained in this part of Scala.js documentation,
@JSImport
is interpreted by the compiler as a JavaScript module import.When you use the
CommonJSModule
module kind (which is the case when you enable theScalaJSBundlerPlugin
), this import is translated into the following CommonJS import:This annotation only tells how your Scala code will be interfaced with the JS world, but it tells nothing about how to resolve the dependency that provides the
THREE
module.With scalajs-bundler you can define how to resolve JS dependencies from the NPM registry by adding the following setting to your
client
project:(And note that you can’t use
jsDependencies
to resolve these modules with@JSImport
)Also, note that the correct CommonJS import to use three.js is
"three"
instead of"THREE"
, so your@JSImport
annotation should look like the following:Alternatively, if you don’t want to resolve your dependencies from the NPM registry, you can supply your CommonJS module as a resource file. Just put it under the
src/main/resources/Scene.js
and refer to it in the@JSImport
as follows:You can see a working example here.