Announcing Scala.js 0.5.0
Jun 13, 2014.
We are very excited to announce the final release of Scala.js 0.5.0! This version is a major milestone towards the maturity of Scala.js, probably the most important release since its very first prototype.
Scala.js is a compiler from Scala to JavaScript. It allows you to write your entire web application in Scala and simply compile to JavaScript!
- Tutorial, for newcomers to Scala.js
- Upgrading from Scala.js 0.4.x
- Try Scala.js right in your browser with Scala.jsFiddle (currently using Scala.js 0.4.4)
New features in the 0.5.x series
Scala.js 0.5.0 introduces new features, improvements and bug fixes in many areas, ranging from compiler correctness to usability to emitted code size and speed.
Language changes
- Scala semantics for integer and character types (i.e., wrapping semantics)
Int,Byte,Short, andCharnow behave the same way as on the JVM with respect to wrapping around their range, e.g.,Intis truly a signed 32-bit integer.- Exception: division by 0 is still unspecified.
Longcontinues to behave as a proper signed 64-bit integer, as it did for a long timeFloatstill behaves just likeDouble, as it always did.- Full details
- Improved interoperability with JavaScript
- Normal Scala primitive types can be used instead of
js.Number,js.Boolean,js.Stringandjs.Undefinedfor interoperability with JavaScript, because they are guaranteed to always be represented as primitive JavaScript values (CharandLongare still opaque to JavaScript, because they do not have a corresponding type in JavaScript). See the documentation on type correspondance for more details. - Introduced the type
js.UndefOr[+A](API), which represents a value of typeAorundefined, and offers anOption-like interface whereundefinedtakes the role ofNone.
- Normal Scala primitive types can be used instead of
Improvements to the generated code
- Smaller. For a non-trivial application, we have
- ~1.3 MB for fast-optimized code (for iterative development)
- ~180 KB for full-optimized code (for production)
- Faster.
- Values of primitive types, excluding
Char, are not boxed anymore when assigned toAnyor generic types - We don’t have precise benchmarks, but we received reports of noticeable improvements.
- Values of primitive types, excluding
sbt plugin changes
preoptimizeJSandoptimizeJShave been renamedfastOptJSandfullOptJS, respectively, to better represent their intent.fastOptJSis really fast (less than 1/2 second in addition to the normalcompileof scalac), and is now the recommended default for iterative development.- Running and testing with Node.js and
PhantomJS
- With
fastOptStage::runorfastOptStage::test, run your code using a native-speed interpreter on the result of fast-optimization. - By default, Node.js is used, unless the setting
requiresDOM := trueis set, in which case PhantomJS is used - Replace
fastOptStagebyfullOptStageto execute the full-optimized version of your code. - Node.js and/or PhantomJS must be installed separately for this to work.
The basic
runandteststill use Rhino and work out-of-the-box.
- With
- Auto-discovery of objects extending the
js.JSApptrait (API)- Can be run directly with the
runtask - With
persistLauncher := true, sbt will emit a tiny JavaScript entry point that calls themainmethod. - To support this the best we could, we have dropped auto-discovery of
objects defining a
def main(args: Array[String])method. - More information in the tutorial
- Can be run directly with the
Binary compatibility and dependency management
- Backward binary compatibility across minor releases
- Similarly to Scala, except it is only backward.
- For example, libraries compiled with Scala.js 0.5.0 will be usable with Scala.js 0.5.1, but not (necessarily) the other way around.
- The sbt plugin encodes the Scala.js binary version in artifact names
in addition to the Scala binary version.
For example, the artifacts for a library “foo” compiled with
Scala 2.11.1 and Scala.js 0.5.0 will be named
foo_sjs0.5_2.11. - To depend on the doubly-cross compiled version of a Scala.js library,
use
%%%instead of%%in yourlibraryDependencies. For example,"org.scala-lang.modules.scalajs" %%% "scalajs-dom" % "0.6"
- Managing your dependencies on JavaScript libraries
- In addition to depending on other Scala.js libraries, Scala.js now supports depending on JavaScript libraries through WebJars, that will be resolved automatically.
- You can ask the sbt plugin to package all your JavaScript dependencies
in a single
.jsfile if you so wish, but this is not mandatory. - See the tutorial for more information.
Command line interface (CLI)
- Following a request by some of our users, we added a
stand-alone distribution that allows to
use Scala.js without sbt (but with Scala).
scalajscis a front-end toscalacsetting up correctly the Scala.js compiler plugin and library on the classpathscalajsldperforms linking and optimizations (the equivalent offastOptJSandfullOptJSin sbt)scalajspprints the content of.sjsirfiles (the intermediate files produced byscalajscand consumed byscalajsld) in a human-readable form.
Upgrading from Scala.js 0.4.x
Source code written for Scala.js 0.4.x should mostly compile without change
for Scala.js 0.5.0. Due to the ability to type JavaScript APIs more precisely,
in particular using scala.Ints and js.UndefOr, it is possible that code
interacting with, for example, the statically typed DOM API will need some
minor changes.
However, build files and HTML files surrounding Scala.js source code will need important adaptations. The easiest is to reproduce the changes of this commit of the bootstrapping skeleton.
You may also wish to take advantage of the new persistLauncher setting to
automatically generate a launcher script based on the discovered JSApp, in
which case you can also apply the changes of
this other commit.
Known issues
This release suffers from a few known issues, which we decided to postpone to a later (binary-compatible) release. The most important ones are:
- #727 -
Source mapping does not work with our Rhino interpreter (with
runandtest)- Prefer
fastOptStage::runandfastOptStage::testto run with Node.js: it is faster and you will get stack traces from your.scalasource files.
- Prefer
- #608 -
Ordering issues with the test reporter, which can mix results of tests
ran in parallel.
- When a test fails, consider using
fastOptStage::testQuickorfastOptStage::testOnlyto rerun only the failing test, which will mitigate this issue.
- When a test fails, consider using
- #706 -
JS libraries that act “too” smartly in Node.js.
- Work around: force usage of PhantomJS instead of Node.js, on which this issue does not seem to manifest.
You can find the complete list of known issues (and report new issues) on GitHub.