Skip to content

Commit 95df5a2

Browse files
committed
Announcing Scala.js 1.17.0, and add doc for the Wasm backend.
1 parent 66972b8 commit 95df5a2

File tree

8 files changed

+267
-2
lines changed

8 files changed

+267
-2
lines changed

_config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ colors: #in hex code if not noted else
6464

6565
### VERSIONS ###
6666
versions:
67-
scalaJS: 1.16.0
67+
scalaJS: 1.17.0
6868
scalaJSBinary: 1
6969
scalaJS06x: 0.6.33
7070
scalaJS06xBinary: 0.6

_data/doc.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@
2828
- text: Emitting modules
2929
url: /doc/project/module.html
3030
- text: JavaScript Environments
31-
url: /doc/project/js-environments.html
31+
url: /doc/project/js-environments.htmlhtml
32+
- text: Emitting WebAssembly
33+
url: /doc/project/webassembly.html
3234
- text: Cross-building
3335
url: /doc/project/cross-build.html
3436
- text: Testing

_data/library/versions.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,4 @@
3333
- 1.12.0
3434
- 1.13.0
3535
- 1.16.0
36+
- 1.17.0
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
---
2+
layout: post
3+
title: Announcing Scala.js 1.17.0
4+
category: news
5+
tags: [releases]
6+
permalink: /news/2024/09/25/announcing-scalajs-1.17.0/
7+
---
8+
9+
10+
We are excited to announce the release of Scala.js 1.17.0!
11+
12+
This release comes with a brand new, shiny, experimental WebAssembly backend.
13+
You can now, under certain conditions, take your existing Scala.js application and compile it to WebAssembly instead.
14+
15+
There were also some bug fixes.
16+
Despite the abnormally long release cycle (v1.16.0 was released 6 months ago), the only external bug report came in 3 weeks ago.
17+
As far as we can tell, nobody was blocked waiting for a bugfix for this long.
18+
19+
Read on for more details.
20+
21+
<!--more-->
22+
23+
## Getting started
24+
25+
If you are new to Scala.js, head over to [the tutorial]({{ BASE_PATH }}/tutorial/).
26+
27+
If you need help with anything related to Scala.js, you may find our community [in `#scala-js` on Discord](https://discord.com/invite/scala) and [on Stack Overflow](https://stackoverflow.com/questions/tagged/scala.js).
28+
29+
Bug reports can be filed [on GitHub](https://github.com/scala-js/scala-js/issues).
30+
31+
## Release notes
32+
33+
If upgrading from Scala.js 0.6.x, make sure to read [the release notes of Scala.js 1.0.0]({{ BASE_PATH }}/news/2020/02/25/announcing-scalajs-1.0.0/) first, as they contain a host of important information, including breaking changes.
34+
35+
This is a **minor** release:
36+
37+
* It is backward binary compatible with all earlier versions in the 1.x series: libraries compiled with 1.0.x through 1.16.x can be used with 1.17.0 without change.
38+
* It is *not* forward binary compatible with 1.15.x: libraries compiled with 1.17.0 cannot be used with 1.16.x or earlier.
39+
* It is *not* entirely backward source compatible: it is not guaranteed that a codebase will compile *as is* when upgrading from 1.16.x (in particular in the presence of `-Xfatal-warnings`).
40+
41+
As a reminder, libraries compiled with 0.6.x cannot be used with Scala.js 1.x; they must be republished with 1.x first.
42+
43+
## Enhancements with compatibility concerns
44+
45+
### Changes to the IR and linker APIs
46+
47+
For tooling authors who directly manipulate the IR and linker APIs, there have been some breaking changes in that area.
48+
This is in line with our version policy for the linker APIs.
49+
50+
The most likely changes you may hit are:
51+
52+
* The reference types in the IR, such as `ClassType` and `ArrayType`, now have a `nullable: Boolean` flag.
53+
There is also a new type `AnyNotNullType`.
54+
* The `NewArray` node does not accept multiple dimensions anymore.
55+
If you want to emit a multi-dimensional array creation, emit a call to `java.lang.reflect.Array.newInstance` instead.
56+
57+
## Enhancements
58+
59+
### Experimental WebAssembly backend
60+
61+
Starting with this release, Scala.js ships with an *experimental* WebAssembly backend.
62+
Under some conditions, you may use it as a drop-in replacement for the usual JavaScript backend.
63+
64+
#### Minimal setup
65+
66+
You can set it up as follows:
67+
68+
{% highlight scala %}
69+
// Emit ES modules with the Wasm backend
70+
scalaJSLinkerConfig := {
71+
scalaJSLinkerConfig.value
72+
.withExperimentalUseWebAssembly(true) // use the Wasm backend
73+
.withModuleKind(ModuleKind.ESModule) // required by the Wasm backend
74+
},
75+
76+
// Configure Node.js (at least v22) to support the required Wasm features
77+
jsEnv := {
78+
val config = NodeJSEnv.Config()
79+
.withArgs(List(
80+
"--experimental-wasm-exnref", // required
81+
"--experimental-wasm-imported-strings", // optional (good for performance)
82+
"--turboshaft-wasm", // optional, bug significantly increases stability
83+
))
84+
new NodeJSEnv(config)
85+
},
86+
{% endhighlight %}
87+
88+
Make sure `node -v` reports at least v22.0.0.
89+
If not, install a newer version.
90+
91+
You are then set up to `run` and `test` your codebase with the WebAssembly backend from sbt.
92+
93+
#### Limitations
94+
95+
Note that the WebAssembly backend *silently ignores* all the `@JSExport` and `@JSExportAll` annotations.
96+
It is never possible to call methods of Scala classes from JavaScript, which includes `toString()`, even through string concatenation.
97+
JavaScript code may still call all public members of JavaScript classes (classes that inherit from `js.Any`).
98+
Moreover, `@JSExportTopLevel` is supported, as well as all the other `@JS...` annotations.
99+
100+
Other than that, we expect the WebAssembly backend to support all of Scala.js semantics.
101+
Please report any issues you may find.
102+
103+
Stack traces are currently suboptimal.
104+
105+
#### Use in browsers
106+
107+
If you want to use it in browsers, you will need:
108+
109+
* For Firefox: in `about:config`, enable `javascript.options.wasm_exnref`.
110+
Also make sure to *disable* `javascript.options.wasm_js_string_builtins`: Firefox has two issues with it that break Scala.js ([1919901](https://bugzilla.mozilla.org/show_bug.cgi?id=1919901) and [1920337](https://bugzilla.mozilla.org/show_bug.cgi?id=1920337))
111+
* For Chrome: in `chrome://flags/`, enable ["Experimental WebAssembly"](chrome://flags/#enable-experimental-webassembly-features).
112+
113+
#### More information
114+
115+
Read more detailed information about [the WebAssembly backend in the docs]({{ BASE_PATH }}/doc/project/webassembly.html).
116+
117+
## Miscellaneous
118+
119+
### New JDK APIs
120+
121+
This release adds support for the following JDK methods:
122+
123+
* In `java.lang.Character`: `codePointAt`, `codePointBefore`, `codePointCount` and `offsetByCodePoints`
124+
* In `java.util.concurrent.ConcurrentHashMap`: `forEach`, `forEachKey` and `forEachValue`
125+
126+
### Unicode version
127+
128+
The Unicode database used by the methods of `java.lang.Character` was updated to Unicode v15.0.
129+
130+
## Bug fixes
131+
132+
Among others, the following bugs have been fixed in 1.17.0:
133+
134+
* [#5026](https://github.com/scala-js/scala-js/issues/5026) Output .js file names can be too long on Windows, esp. for non-ASCII class names.
135+
* [#5044](https://github.com/scala-js/scala-js/issues/5044) `jl.reflect.Array.newInstance()` does not throw the `IllegalArgumentException`s it is supposed to.
136+
137+
You can find the full list [on GitHub](https://github.com/scala-js/scala-js/issues?q=is%3Aissue+milestone%3Av1.17.0+is%3Aclosed).

assets/badges/scalajs-1.17.0.svg

Lines changed: 1 addition & 0 deletions
Loading

doc/all-api.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,16 @@ title: All previous versions of the Scala.js API
55

66
## All previous versions of the API
77

8+
### Scala.js 1.17.0
9+
* [1.17.0 scalajs-library]({{ site.production_url }}/api/scalajs-library/1.17.0/scala/scalajs/js/index.html)
10+
* [1.17.0 scalajs-test-interface]({{ site.production_url }}/api/scalajs-test-interface/1.17.0/)
11+
* [1.17.0 scalajs-javalib-intf]({{ site.production_url }}/api/scalajs-javalib-intf/1.17.0/)
12+
* [1.17.0 scalajs-ir]({{ site.production_url }}/api/scalajs-ir/1.17.0/org/scalajs/ir/index.html)
13+
* [1.17.0 scalajs-linker-interface]({{ site.production_url }}/api/scalajs-linker-interface/1.17.0/org/scalajs/linker/interface/index.html) ([Scala.js version]({{ site.production_url }}/api/scalajs-linker-interface-js/1.17.0/org/scalajs/linker/interface/index.html))
14+
* [1.17.0 scalajs-linker]({{ site.production_url }}/api/scalajs-linker/1.17.0/org/scalajs/linker/index.html) ([Scala.js version]({{ site.production_url }}/api/scalajs-linker-js/1.17.0/org/scalajs/linker/index.html))
15+
* [1.17.0 scalajs-test-adapter]({{ site.production_url }}/api/scalajs-sbt-test-adapter/1.17.0/org/scalajs/testing/adapter/index.html)
16+
* [1.17.0 sbt-scalajs]({{ site.production_url }}/api/sbt-scalajs/1.17.0/#org.scalajs.sbtplugin.package)
17+
818
### Scala.js 1.16.0
919
* [1.16.0 scalajs-library]({{ site.production_url }}/api/scalajs-library/1.16.0/scala/scalajs/js/index.html)
1020
* [1.16.0 scalajs-test-interface]({{ site.production_url }}/api/scalajs-test-interface/1.16.0/)

doc/internals/version-history.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ title: Version history
55

66
## Version history of Scala.js
77

8+
- [1.17.0](/news/2024/09/25/announcing-scalajs-1.17.0/)
89
- [1.16.0](/news/2024/03/19/announcing-scalajs-1.16.0/)
910
- [1.15.0](/news/2023/12/29/announcing-scalajs-1.15.0/)
1011
- [1.14.0](/news/2023/09/25/announcing-scalajs-1.14.0/)

doc/project/webassembly.md

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
---
2+
layout: doc
3+
title: Emitting JavaScript modules
4+
---
5+
6+
# Experimental WebAssembly backend
7+
8+
Since Scala.js 1.17.0, there is an *experimental* WebAssembly backend (Wasm for short).
9+
Under some conditions, it is designed to be a *drop-in* replacement for the usual JavaScript backend.
10+
11+
## Experimental status
12+
13+
Being experimental means that:
14+
15+
* The Wasm backend may be removed in a future *minor* version of Scala.js (or moved to a separate plugin).
16+
* Future versions of Scala.js may emit Wasm that requires *newer* versions of Wasm engines, dropping support for older engines.
17+
18+
However, we do *not* expect the *quality* of the Wasm backend to be any lower than the JS backend.
19+
Feel free to report any issue you may experience with the same expectations as for the JS backend.
20+
21+
## Requirements
22+
23+
The Wasm backend emits code with the following requirements:
24+
25+
* A JavaScript host (i.e., we do not currently generate standalone Wasm)
26+
* A Wasm engine with support for:
27+
* Wasm 3.0
28+
* Wasm GC
29+
* Exception handling, including the latest `exnref`-based variant
30+
* The `ESModule` module kind (see [emitting modules](./module.html))
31+
* Strict floats (which is the default since Scala.js 1.9.0; non-strict floats are deprecated)
32+
33+
Supported engines include Node.js 22, Chrome and Firefox, all using some experimental flags (see below).
34+
35+
## Language semantics
36+
37+
The Wasm backend is nothing but an alternative backend for the Scala.js language.
38+
Its semantics are the same as Scala.js-on-JS, including JavaScript interoperability features, with one big limitation.
39+
40+
### Limitation: no `@JSExport` support
41+
42+
Due to the current feature set of Wasm, it is not possible to implement the semantics of `@JSExport`.
43+
Therefore, the Wasm backend currently *silently ignores* all `@JSExport` and `@JSExportAll` annotations (the latter being sugar for many `@JSExport`s).
44+
45+
This limitation has the following consequences:
46+
47+
* JavaScript code cannot call `@JSExport`ed methods of Scala classes.
48+
* Since that includes `toString()`, instances of Scala classes cannot be converted to string from JavaScript, including as part of string concatenation.
49+
50+
(String concatenation *in Scala.js code* is supported.)
51+
52+
## Minimal setup
53+
54+
The following sbt setup enables the Wasm backend and configures flags for Node.js 22.
55+
56+
{% highlight scala %}
57+
// Emit ES modules with the Wasm backend
58+
scalaJSLinkerConfig := {
59+
scalaJSLinkerConfig.value
60+
.withExperimentalUseWebAssembly(true) // use the Wasm backend
61+
.withModuleKind(ModuleKind.ESModule) // required by the Wasm backend
62+
},
63+
64+
// Configure Node.js (at least v22) to support the required Wasm features
65+
jsEnv := {
66+
val config = NodeJSEnv.Config()
67+
.withArgs(List(
68+
"--experimental-wasm-exnref", // required
69+
"--experimental-wasm-imported-strings", // optional (good for performance)
70+
"--turboshaft-wasm", // optional, bug significantly increases stability
71+
))
72+
new NodeJSEnv(config)
73+
},
74+
{% endhighlight %}
75+
76+
Compared to a setup with ES modules with the JS backend, the above setup should be a drop-in replacement.
77+
The backend emits ES modules with the same layout and interface as those produced by the JS backend.
78+
79+
## Supported engines
80+
81+
Here are some engines known to support enough Wasm features.
82+
83+
### Node.js 22
84+
85+
As mentioned above, Node.js 22 and above requires the following flags:
86+
87+
* `--experimental-wasm-exnref`: required
88+
* `--experimental-wasm-imported-strings`: optional (good for performance)
89+
* `--turboshaft-wasm`: optional, bug significantly increases stability
90+
91+
### Chrome
92+
93+
In `chrome://flags/`, enable ["Experimental WebAssembly"](chrome://flags/#enable-experimental-webassembly-features).
94+
95+
### Firefox
96+
97+
In `about:config`, enable `javascript.options.wasm_exnref`.
98+
99+
Make sure to *disable* `javascript.options.wasm_js_string_builtins`.
100+
Firefox has two issues with it that break Scala.js ([1919901](https://bugzilla.mozilla.org/show_bug.cgi?id=1919901) and [1920337](https://bugzilla.mozilla.org/show_bug.cgi?id=1920337)).
101+
102+
## Performance
103+
104+
Performance of the generated code is currently a hit-or-miss.
105+
Depending on the codebase, it may be several times faster or slower than the JS backend.
106+
107+
Further work on improving performance is ongoing.
108+
Keep in mind that performance work on the Wasm backend is a few months old, compared to a decade of optimizations in the JS backend.
109+
110+
## Implementation details
111+
112+
Looking for some implementation details of how we compile Scala.js to WebAssembly?
113+
Start with [the technical readme of the Wasm backend](https://github.com/scala-js/scala-js/tree/main/linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter#readme).

0 commit comments

Comments
 (0)