Search code examples
javascriptscalasbtscala.js

Scala Scala.js importing JavaScript module gives 'There were linking errors, module support is disabled'


I'm trying to import a JavaScript class module script.js into a scala program main.scala and use its methods add and divide.

I'm using scala.js for importing the JS script and SBT for build.

However when I try running the program, ana error like below:

[info] Fast optimizing D:\Studio\...\target\scala-2.13\add-fastopt

[error] example.MyType needs to be imported from module 'script.js' but module support is disabled

[error] called from example.Hello$.work()void

[error] called from example.Hello$.$js$exported$meth$work()java.lang.Object

[error] exported to JavaScript with @JSExport

[error] involving instantiated classes:

[error] example.Hello$

[error] There were linking errors

[error] (Compile / fastLinkJS) There were linking errors

[error] Total time: 82 s (01:22),

Could you please help me spot where the problem is?

Thanks in advance!

The code looks like so!

main.scala


package example
import scala.scalajs.js
import scala.scalajs.js.annotation._

@js.native
@JSImport("script.js","MyType")
class MyType(var x:Double, var y:Double) extends js.Object {
  def add(z: Int): Double = js.native
  def divide(z: Int): Double = js.native
}

object Hello extends App {
    work() 

    @JSExport
    def work(): Unit = {
        val added = new MyType(1,2).add(3)
        val divided = new MyType(4,3).divide(2)
        
        println(s"Answers: $added, $divided")

    }
}

script.js:


class MyType {
    constructor(x, y) {
    ...
    }

    add(z){
    ...
    }

    divide(z){
    ...
    }
};

module.exports = {MyType};

plugins.sbt:


addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.10.0")
addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.0.0")

build.sbt:


import Dependencies._

ThisBuild / scalaVersion     := "2.13.8"
ThisBuild / version          := "0.1.0-SNAPSHOT"
ThisBuild / organization     := "com.example"
ThisBuild / organizationName := "example"

lazy val root = (project in file("."))
  .settings(
    name := "add",
    libraryDependencies += scalaTest % Test
  )

enablePlugins(ScalaJSPlugin)
scalaJSUseMainModuleInitializer := true

// See https://www.scala-sbt.org/1.x/docs/Using-Sonatype.html for instructions on how to publish to Sonatype.


Solution

  • I imported linker.interface module to build.sbt:

    Then enabled the CommonJSModule and ESModule in the sbt settings.

    This worked for me!

    build.sbt:

    
    import Dependencies._
    import org.scalajs.linker.interface.ModuleInitializer
    
    ThisBuild / scalaVersion     := "2.13.8"
    ThisBuild / version          := "0.1.0-SNAPSHOT"
    ThisBuild / organization     := "com.example"
    ThisBuild / organizationName := "example"
    
    lazy val root = (project in file("."))
      .settings(
        name := "add",
        libraryDependencies += scalaTest % Test
      )
    
    enablePlugins(ScalaJSPlugin)
    scalaJSUseMainModuleInitializer := true
    
    // ECMAScript
    scalaJSLinkerConfig ~= { _.withModuleKind(ModuleKind.ESModule) }
    // CommonJS
    scalaJSLinkerConfig ~= { _.withModuleKind(ModuleKind.CommonJSModule) }
    
    // See https://www.scala-sbt.org/1.x/docs/Using-Sonatype.html for instructions on how to publish to Sonatype.