Much of the documentation around setting up Scala-js (sjs from now on) is focused on SBT but if you are already using maven for your project, integrating sjs with it can become a little difficult. Sjs allows one to compile Scala code to Javascript, that is, if you create a Scala class (a.b.C) and then compile it using Sjs to javascript then that class will be available as a variable in window object and can be accessed as window.a.b.C and can be instantiated as new window.a.b.C() in javascript. So, you can write some code directly in javascript and call some code which you originally wrote in Scala (then converted to JS using sjs). Also, there are many Scala Stubs available for DOM API, JQuery etc. which allow you to interact with DOM from within Scala code. These libraries are available as jars as usual.

Now compilation from Scala code to javascript proceeds in mainly two steps. In first step your code is converted to .sjsir and also .class files. So, for each .class file a .sjsir file is generated. These files contain a sort of intermediate or object code which is later converted to js file. Also, other sjs libraries like library for DOM API, Jquery or standard scalajs library come with both .class and .sjsir files in the jar file. Once .sjsir files for your project have been generated, scalajsld tool is used to generate final javascript file by specifying location of generated .class and .sjsir files and also jar files for dependent libraries. scalajsld then combines all these .sjsir files and generates a single .js file which can be used in an HTML file.

Lets take example of following Hello world ScalaJS app from scala-js website. This app simply uses ScalaJS standard library and DOM API to interact with HTML DOM.

package tutorial.webapp

import scala.scalajs.js.JSApp
import org.scalajs.dom
import dom.document

object TutorialApp extends JSApp {
  def appendPar(targetNode: dom.Node, text: String): Unit = {
     val parNode = document.createElement("p")
     val textNode = document.createTextNode(text)
     parNode.appendChild(textNode)
     targetNode.appendChild(parNode)
  }
  def main(): Unit = {
     appendPar(document.body, "Hello World")
  }
}

Lets create a directory for this project “scalajs-tutorial” and copy above code to a file named “TutorialApp.scala” in “scalajs-tutorial/src/main/scala/tutorial/webapp” folder. Also, create a pom.xml file in “scalajs-tutorial/” folder with following contents

 <?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0                       http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.scalajs</groupId>
<artifactId>scala-js-tutorial-fastopt</artifactId>
<version>1.0.0-SNAPSHOT</version>
<properties>
    <scala.version>2.11.0</scala.version>
    <scalajs.version>0.6.5</scalajs.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.scala-js</groupId>
        <artifactId>scalajs-dom_sjs0.6_2.11</artifactId>
        <version>0.8.0</version>
    </dependency>
    <dependency>
        <groupId>org.scala-js</groupId>
        <artifactId>scalajs-library_2.11</artifactId>
        <version>${scalajs.version}</version>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.scala-tools</groupId>
            <artifactId>maven-scala-plugin</artifactId>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                        <goal>testCompile</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <scalaVersion>${scala.version}</scalaVersion>
                <jvmArgs>
                    <jvmArg>-Xms64m</jvmArg>
                    <jvmArg>-Xmx1024m</jvmArg>
                </jvmArgs>
            </configuration>
        </plugin>
    </plugins>
</build>
</project>

Above is a basic pom file for compiling a standard scala project, it uses maven scala plugin for compiling scala source. It also mentions dependency on scalajs-library and scalajs-dom libary, since our source in TutorialApp makes use of these two libraries. Running mvn clean install on this pom.xml will generate .class files from Scala source and also create a jar file containing those class file under target directory.

In order to generate sjsir files we need to add a scala compiler plugin to this pom file. This plugin is a scala compiler plugin and not a maven plugin. To configure this plugin modify scala maven pluging configuration so that it looks as below.

<plugin>
    <groupId>org.scala-tools</groupId>
    <artifactId>maven-scala-plugin</artifactId>
    <executions>
        <execution>
            <goals>
                <goal>compile</goal>
                <goal>testCompile</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <scalaVersion>${scala.version}</scalaVersion>
        <jvmArgs>
            <jvmArg>-Xms64m</jvmArg>
            <jvmArg>-Xmx1024m</jvmArg>
        </jvmArgs>
        <compilerPlugins>
            <compilerPlugin>
                <groupId>org.scala-js</groupId>
                <artifactId>scalajs-compiler_2.11.0</artifactId>
                <version>0.6.4</version>
            </compilerPlugin>
        </compilerPlugins>
    </configuration>
</plugin>

Here we added compilerPlugins tag to configuration section of scala maven plugin and also specified GAV of scalajs compiler plugin. Now if you run mvn clean install, it should generate .sjsir files along with .class files under target/classes directory.

Our next step is to generate final js file. Unfortunately, there is no maven plugin to do this yet, instead there is a command line utility provided by scala-js, which we can invoke from maven to generate the final js file. To obtain the command line utility download standalone distribution of scalajs from scalajs website [0]. Untar/unzip the distribution and add bin directory inside the expanded archive to your PATH enviornment variable. Make sure to give execute permissions to all files in this directory. Now, to invoke this from maven, lets add following maven exec plugin to plugins tag in pom.xml

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <executions>
        <execution>
            <id>final-js</id>
            <phase>package</phase>
            <goals>
                <goal>exec</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <executable>scalajsld</executable>
        <commandlineArgs>-d target --output target/${project.artifactId}.js target/classes ${jartoLink.paths}</commandlineArgs>
    </configuration>
</plugin>

This exec plugin will run “scalajsld” command with target as destination directory (-d option) and name of the generated final js file is specified using –output argument, in this example it is project artifact id .js. Finally we specify location of all .sjsir files. target/classes contains .sjsir files for our project. We then specify paths to all library jar file files using variable “jartoLink.paths”. This variable contains paths to all jar files in in local file system (.m2 repository) specified in dependencies sections. This variable is set using maven dependency plugin. Add following plugin in pom xml plugins section to make this work.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.10</version>
    <executions>
        <execution>
            <id>build-classpath</id>
            <phase>generate-sources</phase>
            <goals>
                <goal>build-classpath</goal>
            </goals>
            <configuration>
                <outputProperty>jartoLink.paths</outputProperty>
            </configuration>
        </execution>
    </executions>
</plugin>

Now, if you run mvn clean install, it should generate scala-js-tutorial-fastopt.js file in target directory. You can now include this in an HTML page as follows.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>The Scala.js Tutorial</title>
  </head>
  <body>
    <!-- Include Scala.js compiled code -->
    <script type="text/javascript" src="./target/scala-js-tutorial-fastopt.js"></script>
    <!-- Run tutorial.webapp.TutorialApp -->
    <script type="text/javascript">
      tutorial.webapp.TutorialApp().main();
    </script>
  </body>
</html>

Place above HTML file in “scalajs-tutorial” directory. If you open this file in browser you should be see “Hello World”. Scala js is a great tool as it allows one to use advanced features of scala for writing javascript code. As more and more scala js libraries become available to use with scala js, it will make writing and most importantly maintaining Javascript code. Scala JS automatically gives you static typing, packages, pattern matching, Options, flatMap etc. It also allows you to write common code for both server and client only once. [0] http://www.scala-js.org/doc/internals/downloads.html