Build / Compile latest SalaJS (1.3+) using gradle on a windows machine?

Viewed 125

Does anyone know if this is possible? I have ran into the following solutions:

  1. There is a shell script that can act as 'sbt' and can be invoked in gradle using an 'exec' task but it is limited to a linux OS. I would ideally like an OS independent solution.

  2. There is a gradle plugin for scalajs but it is relatively old (and seems no longer maintained), supporting up to version 0.6, whereas scalajs is already on version 1.3+.

ScalaJs has a 'scalajs-compiler' jar, and I am wondering if this can be used to compile a scalajs project rather than relying on SBT, if there is any documentation covering this, a reference will be greatly appreciated. Thank you all for your help.

1 Answers

Scala.js CLI

The Scala.js CLI (GitHub / Download) should work with *NIX systems and windows. However, there is another problem: it doesn't automatically use new versions of Scala.js. So currently, it will only give you Scala.js 1.0.0 functionality. We have not yet figured out how to solve this problem.

Compiling Scala.js yourself

The Scala.js compiler is simply a Scala compiler plugin. You simply need to invoke the Scala compiler with additional arguments:

scalac \
  -classpath $CLASSPATH:scalajs-library_2.13-1.4.0.jar \
  -Xplugin:scalajs-compiler_2.13.4-1.4.0.jar \
  $FILES

This will produce .class and .sjsir files for the provided .scala files.

The versions of scalajs-library / scalajs-compiler must match the version of Scala you are compiling. Further, note that the compiler version must match exactly, the library needs to match in the minor version.

Linking Scala.js yourself

Unlike Scala for the JVM, Scala.js requires a linking step. The Scala.js linker comes as a standalone library. (artifacts on maven, Interface API).

Both the Scala.js CLI and the sbt plugin use this library to link Scala.js code. However, the CLI is outdated and the sbt plugin complicated. So instead of linking to an example, I'll just provide one here:

import java.nio.file.Path

import org.scalajs.logging._
import org.scalajs.linker.StandardImpl
import org.scalajs.linker.interface._

import scala.concurrent.ExecutionContext.Implicits.global

def link(classpath: Seq[Path], outputDir: Path): Unit = {
  val logger = new ScalaConsoleLogger(Level.Warn)
  val linkerConfig = StandardConfig() // look at the API of this, lots of options.
  val linker = StandardImpl.linker(linkerConfig)

  // Same as scalaJSModuleInitializers in sbt, add if needed.
  val moduleInitializers = Seq()

  val cache = StandardImpl.irFileCache().newCache
  val result = PathIRContainer
    .fromClasspath(classpath)
    .map(_._1)
    .flatMap(cache.cached _)
    .flatMap(linker.link(_, moduleInitializers, PathOutputDirectory(outputDir), logger))

  Await.result(result, Duration.Inf)
}

This will link all the Scala.js code in classpath and put the resulting file(s) into outputDirectory.

Related