Scala.js support in Scala 3

(The Scala Org aims to release Scala 3 by the end of fall 2020. We are about 15 employees (some of whom work part-time), spread in 4 organisations (+ active community members), focusing on finalising 52 essential projects in 6 months. As of today, project leads will publish the road-maps under the category “Scala 3 release projects” to share with you what is to be expected and hopefully get your advice & contributions as well. All the projects’ road-maps come after an extensive feedback gathering, rounds of discussion, and involvement of major stakeholders, we now need the community to help push this effort over the line. Your collaboration is highly appreciated, thank you in advance!)

At the moment, the Scala 3 compiler has partial support for Scala.js under the -scalajs flag. There is still a lot of work to fully cover what Scala.js for Scala 2 supports. This project consists in completing the support of Scala.js in Scala 3.

The main measure of success for this project is to make all JUnit tests of Scala.js (for Scala 2) pass in Scala 3.

The project is decomposed in 4 main milestones, targeting subsets of language features.

M1: Portable subset of Scala (Completed)

This milestone includes the portable subset of Scala, i.e., code that cross-compiles under Scala/JVM and Scala.js. The corresponding tests are those in the shared/ directory of the Scala.js test suite.

This milestone has already been completed in the past two weeks.

M2: Scala -> JS interop (Completed)

This milestone includes all the interoperability features of Scala.js in the direction Scala -> JS. This excludes exports (@JSExport* annotations) and non-native JS classes (classes that extend js.Any but are not marked with @js.native).

Edit: This milestone was completed around August 25.

M3: Non-native JS classes (Completed)

This milestone includes the definition of non-native JS classes, i.e., classes (and objects) that extend js.Any but do not have the @js.native annotation. Those classes have JavaScript semantics (notably wrt. run-time overloading resolution and JavaScript visibility) while being implemented in Scala.js.

M4: Exports (Completed - pending new release)

The last milestone includes the support for exports, i.e., all @JSExport* annotations and their effects.

The pull request for exports was merged in dotty master. It will be part of the next release.


Update: the milestones M1 and M2 have been completed and released in Dotty 0.27.0-RC1. It is now possible to use Scala.js with Dotty as long as you’re not using non-native JS classes nor exports.


Doesn’t there need to be at least one export in order to be able to invoke it, and in order for it to not eliminate everything as dead code?

No, there doesn’t. That was true a very long time ago, but it’s been ages since we’ve had main methods that are not export-driven. So you can have a def main(args: Array[String]): Unit, and that would be called when the .js file is loaded. All without any export.

That’s exciting, I’m so glad that SJS is going to be a part of compiler soon. Thanks!


An update:

  • The support for non-native JS classes was merged a while ago, and shipped as part of Scala 3.0.0-M1 (which is on Maven Central, but hasn’t been widely announced yet)
  • The support for JS exports is in a PR, pending review: (edit: it has since been merged)

That completes this project. The next milestone of Scala 3 will therefore have complete support for Scala.js.


One aspect which isn’t supported yet I think are the custom Scala.js flags: