Announcing Scala.js 0.6.26

Nov 29, 2018.

We are pleased to announce the release of Scala.js 0.6.26!

The highlight of this release is the support for ECMAScript modules. It also fixes a few issues.

Starting from 0.6.26 in the 0.6.x branch, Scala.js has been relicensed under the Apache License 2.0, following the corresponding relicensing of Scala upstream. Scala.js 1.x milestones have also been relicensed since version 1.0.0-M6.

Read on for more details.

Getting started

If you are new to Scala.js, head over to the tutorial.

Release notes

If you use .scala build files in project/ and are upgrading from Scala.js 0.6.22 or earlier, do read the release notes of 0.6.23, which contain a source breaking change in that situation.

If upgrading from Scala.js 0.6.14 or earlier, make sure to read the release notes of 0.6.15, which contain important migration information.

As a minor release, 0.6.26 is backward binary compatible with previous releases in the 0.6.x series. Libraries compiled with earlier versions can be used with 0.6.26 without change. 0.6.26 is also forward binary compatible with 0.6.{17-25}, but not with earlier releases: libraries compiled with 0.6.26 cannot be used by projects using 0.6.{0-16}.

Please report any issues on GitHub.

Top-level exports with namespaces are deprecated

Top-level exports with namespaces, such as

@JSExportTopLevel("foo.Bar")
object Bar

are deprecated, as they do not have a good equivalent in ECMAScript modules.

If necessary, you can use the following idiom instead:

package mypack

// not directly exported
object Bar

object TopLevelExports {
  @JSExportTopLevel("foo")
  val foo = new js.Object {
    val Bar = mypack.Bar
  }
}

The deprecation warning can be silenced in the 0.6.x series with

scalacOptions += "-P:scalajs:suppressExportDeprecations"

Support for ECMAScript modules

Scala.js can now emit a project as an ECMAScript module, in addition to a script or a CommonJS module. This can be enabled with

scalaJSLinkerConfig ~= { _.withModuleKind(ModuleKind.ESModule) }

In that case, @JSImport and @JSExportTopLevel will straightforwardly map to ECMAScript import and export statements:

Scala.js
@JSExportTopLevel("foo")
object Bar
ECMAScript
export { Bar as foo }
Scala.js
@js.native
@JSImport("mod.js", "foo")
object Bar extends js.Object
ECMAScript
import { foo as Bar } from "mod.js"
Scala.js
@js.native
@JSImport("mod.js", JSImport.Namespace)
object Bar extends js.Object
ECMAScript
import * as Bar from "mod.js"
Scala.js
@js.native
@JSImport("mod.js", JSImport.Default)
object Bar extends js.Object
ECMAScript
import Bar from "mod.js"

To run and test such a project, Node.js v10.2.0 or later is required. We recommend v10.12.0 or later, as it is the version that we continuously test. In addition, you will need a few additional settings:

jsEnv := {
  new org.scalajs.jsenv.NodeJSEnv(
      org.scalajs.jsenv.NODEJSEnv.Config()
        .withArguments(List("--experimental-modules"))
  )
}

artifactPath in (proj, Compile, fastOptJS) :=
  (crossTarget in (proj, Compile)).value / "myproject.mjs"

artifactPath in (proj, Test, fastOptJS) :=
  (crossTarget in (proj, Test)).value / "myproject-test.mjs"

The first setting is required to enable the support of ES modules in Node.js. The other two make sure that the JavaScript produced have the extension .mjs, which is required for Node.js to interpret them as ES modules.

The support for running and testing ES modules with Node.js is experimental, as the support of ES modules by Node.js is itself experimental. Things could change in future versions of Node.js and/or Scala.js.

Bug fixes

Among others, the following bugs have been fixed in 0.6.26:

  • #3445 Linking error on Array() pattern with Scala.js 0.6.25 and Scala 2.13.0-M4
  • #3280 Matcher.groupCount behaviour inconsistent between JS and JVM
  • #3492 Double underscore __ should not be forbidden in top-level exports

You can find the full list on GitHub.