Integrating Scala-js into an existing project, Part 1

It can be useful to get rid of Javascript and switch to a better typed language such as Typescript or Scala. Both compile to Javascript.

In this blog post, I will describe how work with scala-js to transform the existing javascript files of a project to scala and have the compilation pipeline work as usual.

Assuming you are working with sbt > 0.13, and your project is inside the folder mainprojectfolder, do the following:

    1. Make sure the file mainprojectfolder/project/plugins.sbt exists and contains the following line :
      addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.4")
    2. Modify the build.sbt file of your top-level project to compile the javascript project when it is built. Add the following lines:
      lazy val js = (project in file("js")).enablePlugins(ScalaJSPlugin)
      scalaVersion in js := "2.11.1" // Or the right version
      addCommandAlias("runWithJS", ";fastOptJS;run")
    3. Make sure the definition of the root includes the following aggregation keyword.
      lazy val root = project(...).aggregate(js)
    4. Create your scala file(s) at  mainprojectfolder/js/src/main/scala/your/package/myscript.scala with the following content (or something from the tutorial):
    5. package your.package
      import scala.scalajs.js.JSApp
      object YourApp extends JSApp {
        def main(): Unit = {
          println("Hello world!")
        }
      }

      Now, after running sbt  inside mainprojectfolder I, you can launch the following  new tasks:
      fastOptJS  which compiles the new scala file above to javascript
      runWithJS  which performs the fastOptJS  above plus the run command (you can customize this according to your needs).

      These two tasks both create the following files inside mainprojectfolder/js/target/scala-2.11 :
      jsproject-fastopt.js: This file needs to be included in the final html.
      jsproject-fastopt.js.map: This is the source map
      jsproject-jsdeps.js: This file needs to be included in the final html. It contains all the remaining dependencies.

    6. You may be interested to copy the generated javascript files to another folder like mainprojectfolder/public/js. For that, add the following line in the build.sbt file:
      lazy val copyjs = TaskKey[Unit]("copyjs", "Copy javascript files to target directory")
      copyjs := {
        val outDir = baseDirectory.value / "public/js"
        val inDir = baseDirectory.value / "js/target/scala-2.11"
        val files = Seq("js-fastopt.js", "js-fastopt.js.map", "js-jsdeps.js") map { p =>   (inDir / p, outDir / p) }
        IO.copy(files, true)
      }

      and of course update the custom command in the same file:

      addCommandAlias("runWithJS", ";fastOptJS;copyjs;run")

Next: Part 2: Integrating DOM and jQuery