In this recipe you’ll learn how to:

  • Create a basic Scala.js project
  • … with a custom name
  • … and package structure

As an example, we’ll set-up a project for a “countdown” application.

Cloning the sample application

We’ll start by cloning the sample-application provided by Sébastien Doeraene.

Assuming “git” is installed in your machine, you need to clone this project:

https://github.com/sjrd/scala-js-example-app

Rename the resulting directory “scala-js-example” to “countdown-example”.

Changing the project name

Look at the directory structure. Edit ”buid.sbt”, change the name to “Countdown Example”.

name := "Countdown Example"

I am using a string with a space on purpose to handle this more “tricky” case. Normally, just “Countdown” would suffice.

Changing the Packages

Renaming the packages might be easier to accomplish from within an IDE than directly manipulating directories.

In this case you should generate the IDE project first, and then import it (using the SBT plugins for either Eclipse or IntelliJ).

After having imported the project to your IDE, do the following:

  • rename the package “example” (in “main”) to “com.sebnozzi.countdown”
  • rename the package “example.test” (in “test”) also to “com.sebnozzi.countdown”

For Eclipse, watch out for Scala-IDE bugs. The package names, or the imports, in the Scala files might be scrambled or wrong :-(

At the end, the directory structure should match this:

  • src/main/scala/com/sebnozzi/countdown/ScalaJSExample.scala
  • src/test/scala/com/sebnozzi/countdown/ScalaJSExampleTest.scala

And the the Scala classes should refer to the new package:

package com.sebnozzi.countdown

Renaming the classes

Rename both file-names and classes…

  • from “ScalaJSExample” to “CountdownExample[.scala]”.
  • from “ScalaJSExampleTest” to “CountdownExampleTest[.scala]”.

Make sure that you rename both files and classes, as in Scala they don’t need to match.

Also watch out for the test class, since it references (imports) the main class. If your IDE didn’t pick up the rename, you’ll have to fix it yourself:

it("should implement square()") {
 import CountdownExample._

Lastly, though not critical, it would also be correct to change this line in the test class:

describe(“ScalaJSExample”) {

to:

describe(“CountdownExample”) {

Fixing the JavaScript file-references

The HTML files “index-dev.html” and “index.html” are used to “host” the Scala.js application. They load the generated JavaScript files, which the SBT plugin generates somewhere under “target”.

Since the generated file-names correspond to the SBT-project’s name (which we renamed), the HTML files need to be updated.

In “index-dev.html” you need to change:

  • “example-extdeps.js” to “countdown-example-extdeps.js”
  • “example-intdeps.js” to “countdown-example-intdeps.js”
  • “example.js” to “countdown-example.js”

And in “index.html“:

  • “example-opt.js” to “countdown-example-opt.js”

Fixing the bootstrap file (startup.js)

There is one last very special file that needs to be updated. Under the directory “js” you’ll find “startup.js“.

This JavaScript file kick-starts the Scala.js application by calling the “main()” method of the main class.

As you might have notices, nowhere in the HTML files is “startup.js” referenced. Instead, it is referenced in “build.sbt” build-file. When generating code, Scala.js includes the contents of “startup.js” in the resulting JavaScript files.

We need to change both the references to the package and the main class (the method name did not change). The convention to use for the package name is to replace the dots “.” with underscores “_”.

The end-result should look like:

ScalaJS.modules.com_sebnozzi_countdown_CountdownExample().main();

Making sure it works

Generate the development (unoptimized) version with “packageJS” from the SBT-console:

sbt> packageJS

Once finished, load the “index-dev.html” file in your browser.

Loading the development version takes from less than 1 second to more than 5, depending on your setup and browser. Experiment with different browsers, as some are much faster than others (in turn, depending on your operating system).

You should read “It works!”.

Just to be sure, try out the optimized version as well. Again, on the SBT-console run:

sbt> optimizeJS

WARNING: while the optimization process produces a very small and fast file, it takes some time to do so. On my setup it’s around 2 minutes. This is mode is intended for “deployment” situations.

Once done, open “index.html”. It should load immediately and again you should read “It works!”.

Last but not least, let’s check that the tests work. On the SBT console, run:

sbt> test

The tests should all pass.

Wrap-up

In this recipe you learned how to set-up a basic Scala.js with custom class names and package.

This should give you what you need to start your own Scala.js projects.