Florian Baierl
Florian Baierl

Reputation: 2481

Setup a scala.js cross compiled library

I have a small Scala library that I want to make use of in a Scala.js application: https://github.com/fbaierl/scala-tarjan

For that reason, I have decided to create a cross-compiled library that compiles to both Scala.js and Scala JVM: https://github.com/fbaierl/scalajs-cross-compile-tarjan. But I am a bit stuck on how to continue from here on.

So far I have all the relvant code inside the shared directory:

and two Tarjan.scala classes for both the JVM and the JS part here:

These are supposed to be public "interface classes" for both JVM and JS that just call methods from the shared library.

js/src/main/scala/Tarjan.scala:

import com.github.fbaierl.tarjan.{TarjanRecursive => lib}
import scala.scalajs.js.annotation.{JSExport, JSExportTopLevel}

@JSExportTopLevel("Tarjan")
object Tarjan {
   @JSExport
   def tarjan[T](g: Map[T, List[T]]): Unit = lib.tarjan(g)
}

jvm/src/main/scala/Tarjan.scala:

import com.github.fbaierl.tarjan.{TarjanRecursive => lib}

object Tarjan {
  def tarjan[T](g: Map[T, List[T]]): Unit = lib.tarjan(g)
}

Is this generally the correct approach? Can I compile the project like that and publish to e.g. Sonatype?

Upvotes: 2

Views: 316

Answers (1)

Toxaris
Toxaris

Reputation: 7266

Instead of duplicating the "interface classes" for JS and JVM, you might want to use the scalajs-stubs library to be able to use @JSExportTopLevel and @JSExport in the shared code.

shared/src/main/scala/Tarjan.scala:

import com.github.fbaierl.tarjan.{TarjanRecursive => lib}
import scala.scalajs.js.annotation.{JSExport, JSExportTopLevel}

@JSExportTopLevel("Tarjan")
object Tarjan {
  @JSExport
  def tarjan[T](g: Map[T, List[T]]): Unit = lib.tarjan(g)
}

build.sbt:

… .jvmSettings(
  libraryDependencies += "org.scala-js" %% "scalajs-stubs" % scalaJSVersion % "provided"
)

See "Exporting shared classes to JavaScript" at the bottom of https://www.scala-js.org/doc/project/cross-build.html.

Upvotes: 2

Related Questions