Skip to content

Commit 0f76437

Browse files
committed
Announcing Scala.js 0.6.0-RC1.
1 parent 8c75764 commit 0f76437

File tree

4 files changed

+281
-1
lines changed

4 files changed

+281
-1
lines changed
Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
---
2+
layout: post
3+
title: Announcing Scala.js 0.6.0-RC1
4+
category: news
5+
tags: [releases]
6+
---
7+
{% include JB/setup %}
8+
9+
We are excited to announce the first release candidate of Scala.js 0.6.0, aka 0.6.0-RC1!
10+
Unless there are blocking issues with this RC, or issues requiring binary incompatible changes, this version will become 0.6.0 final.
11+
12+
Scala.js 0.6.0-RC1 is not forward nor backward binary compatible with M1/M2/M3.
13+
14+
To upgrade from 0.6.0-Mx, simply change the version number.
15+
If you're upgrading from M1/M2, you might need to address some compilation errors regarding the `js` package, but it should be straightforward.
16+
Should you encounter any trouble, do not hesitate to ask.
17+
18+
The rest of this announcement is cumulative with the changes introduced in the milestones, and is therefore written wrt. 0.5.6.
19+
20+
<hr/>
21+
22+
As the change in "major" version number witnesses, this release is *not* binary compatible with 0.5.x.
23+
Libraries need to be recompiled and republished using 0.6.0-RC1 to be compatible.
24+
More importantly, this release is not source compatible with 0.5.x either.
25+
26+
Please report any issues [on GitHub](https://github.com/scala-js/scala-js/issues).
27+
28+
The following libraries and testing frameworks have already been upgraded and published for 0.6.0-RC1:
29+
30+
* [DOM types](https://github.com/scala-js/scala-js-dom): `"org.scala-js" %%% "scalajs-dom" % "0.7.0"`
31+
* [jQuery types](https://github.com/scala-js/scala-js-jquery): `"be.doeraene" %%% "scalajs-jquery" % "0.7.0"`
32+
* [Scala.rx](https://github.com/lihaoyi/scala.rx): `"com.lihaoyi" %%% "scalarx" % "0.2.7-RC1"`
33+
* [ScalaTags](https://github.com/lihaoyi/scalatags): `"com.lihaoyi" %%% "scalatags" % "0.4.3-RC1"`
34+
* [Autowire](https://github.com/lihaoyi/autowire): `"com.lihaoyi" %%% "autowire" % "0.2.4-RC1"`
35+
* [µPickle](https://github.com/lihaoyi/upickle): `"com.lihaoyi" %%% "upickle" % "0.2.6-RC1"`
36+
* [µTest](https://github.com/lihaoyi/utest): `"com.lihaoyi" %%% "utest" % "0.2.5-RC1" % "test"`
37+
38+
## Preparations before upgrading from 0.5.x
39+
40+
### Upgrade to 0.5.6 if not already done
41+
42+
Before upgrading to 0.6.0-RC1, **we strongly recommend that you upgrade to Scala.js 0.5.6**, and address all deprecation warnings.
43+
Scala.js 0.5.6 contains warnings for the most vicious breaking changes of 0.6.x.
44+
45+
### Migrate away from the Jasmine test framework
46+
47+
If you use the Jasmine test framework, migrate away from it to one of the other testing frameworks for Scala.js.
48+
The Jasmine test framework is *not* a good testing framework for Scala.js code, and is being *removed* in 0.6.x.
49+
50+
Possible replacements:
51+
52+
* [uTest](https://github.com/lihaoyi/utest)
53+
* [Little Spec](https://github.com/eecolor/little-spec)
54+
* [otest](https://github.com/cgta/otest)
55+
* [MiniTest](https://github.com/monifu/minitest)
56+
57+
Note that these testing frameworks also need to upgrade to 0.6.0-RC1 before you can use them.
58+
59+
## Upgrade to 0.6.0-RC1 from 0.5.6
60+
61+
Basically, you need to apply the same kind of changes to your build files as in [this commit](https://github.com/sjrd/scala-js-example-app/commit/77d5f970267247c714a164f3dd72e51605f3ef66), which mostly consists in:
62+
63+
* Upgrade to sbt >= 0.13.6 (the current version is 0.13.7).
64+
* Adaptations to new groupId and artifact names for Scala.js packages.
65+
* Adaptation to the new `AutoPlugin` infrastructure of the sbt plugin.
66+
* Drop the prefix `ScalaJSKeys.` for Scala.js-specific sbt keys, as they are not needed anymore.
67+
* Upgrade to 0.6.0-RC1-enabled versions of your dependencies.
68+
69+
On the sbt command line, not much changes, except the way you use the `fastOpt` and `fullOpt` mode.
70+
In Scala 0.5.x, you could run in `fastOpt` mode with:
71+
72+
> fastOptStage::run
73+
74+
In 0.6.x, the mode is regulated by the setting `scalaJSStage`, which is one of:
75+
76+
* `PreLinkStage` (default): uses Rhino
77+
* `FastOptStage`: `fastOpt` mode, uses Node.js or PhantomJS
78+
* `FullOptStage`: `fullOpt` mode, uses Node.js or PhantomJS
79+
80+
You can change it from the command line with
81+
82+
> set scalaJSStage := FastOptStage
83+
> run # runs in fastOpt mode
84+
85+
In a multi-project build, you'll want to change it for all projects, which can be done with `in Global`:
86+
87+
> set scalaJSStage in Global := FastOptStage
88+
89+
## Major changes
90+
91+
This section discusses major changes affecting source compatibility, which may or may not apply to your project.
92+
93+
### `ClassCastException` becomes an undefined behavior
94+
95+
The JVM, in its incommensurable magnanimity, throws nicely specified exceptions when you do something bad with your code.
96+
For example, it will nicely throw a `ClassCastException` if you perform an invalid `.asInstanceOf`, or an `ArithmeticException` if you divide an integer by 0.
97+
98+
Since the beginning of time, Scala.js has handled most of these things as *undefined behavior*, i.e., *anything can happen* if these cases happen.
99+
Until 0.5.x, `ClassCastException`s were properly reported, though.
100+
We have found, however, that checking these buggy cases costs up to 100% overhead to the overall execution time of a Scala.js program.
101+
102+
In Scala.js 0.6.x, therefore, invalid casts become an undefined behavior as well.
103+
However, the compiler will *still* be nice with you *in fastOpt mode*, by throwing an `UndefinedBehaviorError` if you perform an invalid cast (instead of a `ClassCastException`).
104+
`UndefinedBehaviorError` is a *fatal* error, meaning it won't be caught by `case NonFatal(e)` handlers.
105+
In fullOpt mode, the checks are removed for maximum efficiency.
106+
107+
You *must not catch* `UndefinedBehaviorError`, since that would cause your program to behave differently in fastOpt mode than in fullOpt.
108+
The idea of `UndefinedBehaviorError` is that you can enjoy strict checks and stack traces while developing.
109+
110+
If you really want `ClassCastException`s to be thrown reliably (both in fastOpt and fullOpt modes), you can enable them in your application, at the expense of runtime performance, with the following sbt setting:
111+
112+
{% highlight scala %}
113+
scalaJSSemantics ~= { _.withAsInstanceOfs(org.scalajs.core.tools.sem.CheckedBehavior.Compliant) }
114+
{% endhighlight %}
115+
116+
This applies to the entire application, including dependencies.
117+
There is no way to select parts of the application where this applies, because there is no way to make that sensical.
118+
119+
### The `scala.scalajs.js` package has been simplified
120+
121+
We have removed a lot of historical warts from the `scala.scalajs.js` package, mostly types and APIs with equivalents among normal Scala types and libraries:
122+
123+
* `js.String`, `js.Boolean`, `js.Number` and `js.Undefined` have been removed, as well as their `js.prim.*` equivalent.
124+
`String`, `Boolean`, `Double` and `Unit` should be used instead.
125+
* `js.parseInt(s)` and `js.parseFloat(s)` should be replaced by `s.toInt` and `s.toDouble`.
126+
* `js.NaN`, `js.Infinity` should be replaced by `Double.NaN` and `Double.PositiveInfinity`.
127+
* `js.isNaN(x)` should be replaced by `x.isNaN`.
128+
* `js.isFinite(x)` should be replaced by `!x.isNaN && !x.isInfinite`.
129+
130+
Methods provided by ECMAScript 5.1 on primitive strings and numbers can be enabled by importing the following implicit conversions:
131+
132+
{% highlight scala %}
133+
import js.JSStringOps._
134+
import js.JSNumberOps._
135+
{% endhighlight %}
136+
137+
### `js.native` in facade types
138+
139+
When writing facade types, it was previously recommended to use `???` as a fake body for fields and methods.
140+
You should now use `js.native` instead, as in:
141+
142+
{% highlight scala %}
143+
trait Foo extends js.Object {
144+
var bar: Int = js.native
145+
def foobar(x: Int): String = js.native
146+
}
147+
{% endhighlight %}
148+
149+
The compiler will emit a warning if you use any other body.
150+
The warning will become an error in 1.0.0.
151+
152+
### `@JSExport` exports to fully qualified names by default
153+
154+
As announced by deprecation warnings in the 0.5.6 compiler, putting `@JSExport` without an explicit name on an `object` or `class` changes meaning between 0.5.x and 0.6.x.
155+
Consider this code:
156+
157+
{% highlight scala %}
158+
package babar
159+
160+
@JSExport
161+
class Foo
162+
{% endhighlight %}
163+
164+
In 0.5.x, `Foo` is exported as `Foo`.
165+
In 0.6.x, it is exported as `babar.Foo` instead.
166+
167+
### Testing frameworks adaptations
168+
169+
If you are not a testing framework implementor, this section does not apply to you.
170+
Please follow the migration guidelines of any testing framework you may use.
171+
172+
Until 0.5.x, Scala.js had a custom, ad-hoc substitute for the sbt testing interface, which allows testing frameworks to integrate with sbt.
173+
Although quite good in its own right, it suffered from several limitations, including the inability for one project to use more than one testing framework at the same time.
174+
Scala.js 0.6.x now supports its JS version of the original sbt testing interface, with all its power, API, and usability features.
175+
We also offer tools to make your testing framework fully source-compatible with the JVM and JS variants of the testing interface, without a single line of platform-specific source code.
176+
177+
An existing barebone cross-compiling testing framework can be found [in our tests](https://github.com/scala-js/scala-js/tree/v0.6.0-RC1/sbt-plugin-test).
178+
Some highlights:
179+
180+
* [Build definition for the cross-compiling framework](https://github.com/scala-js/scala-js/blob/v0.6.0-RC1/sbt-plugin-test/build.sbt#L49-L64)
181+
* [(Cross-compiling) source code of the testing framework](https://github.com/scala-js/scala-js/tree/v0.6.0-RC1/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework)
182+
* [Build definition for a cross-compiling project using the framework](https://github.com/scala-js/scala-js/blob/v0.6.0-RC1/sbt-plugin-test/build.sbt#L66-L86)
183+
* [Source code of the project using the framework](https://github.com/scala-js/scala-js/tree/v0.6.0-RC1/sbt-plugin-test/multiTest)
184+
185+
Adapting your testing framework to follow this structure is likely to be the easiest path of migration.
186+
You may also want to take a look at [the PR we made to uTest](https://github.com/lihaoyi/utest/pull/45) to migrate to Scala.js 0.6.x.
187+
188+
Should you run into trouble, don't hesitate to ask on the mailing list!
189+
190+
## Enhancements
191+
192+
### <a name="cross-project"></a> Defining cross-compiling projects with `crossProject`
193+
194+
When writing cross-compiling code, we need to have two separate projects in sbt for the JVM target and the JS target.
195+
The new `CrossProject` type, and its `crossProject` builder, helps in defining these pairs of projects in a DRY way.
196+
197+
See the [documentation of `CrossProject`]({{ BASE_PATH }}/api/sbt-scalajs/0.6.0-RC1/#org.scalajs.sbtplugin.cross.CrossProject) for more information and examples.
198+
199+
### Faster!
200+
201+
Scala.js 0.6.x benefits from many performance improvements, most notably:
202+
203+
* `asInstanceOf`s are unchecked (see above), giving `fullOpt` code up to twice as fast as before
204+
* `Range.foreach`, aka the `for (i <- 0 until n)` kind of loops, is inlined away, giving the same performance as an explicit `while` loop.
205+
* Higher-order operations on `js.Array`s and `js.Dictionary`s (such as `foreach`, `map`, etc.) are inlined away as `while` loops.
206+
* Various improvements to the optimizer.
207+
208+
### Scala collection API for `js.Array[A]` and `js.Dictionary[A]`
209+
210+
The title says it all: `js.Array[A]` and `js.Dictionary[A]` receive the entire Scala collection API, respectively of `mutable.Buffer[A]` and `mutable.Map[String, A]`.
211+
212+
`js.Array` becomes the default implementation of `mutable.Buffer`, i.e., `mutable.Buffer.empty` returns a `js.Array` wrapped in a `js.WrappedArray`.
213+
214+
### Implicits to make "writing JavaScript" easier
215+
216+
Sometimes, for example when porting existing JavaScript code, we want to just "write JavaScript" inside our Scala.js code.
217+
A new object `js.DynamicImplicits` ([API]({{ BASE_PATH }}/api/scalajs-library/0.6.0-RC1/#scala.scalajs.js.DynamicImplicits$) provides implicit conversions that allow to write dynamically typed JavaScriptish code directly in Scala.js with a mimimal amount of boilerplate.
218+
Needless to say, these implicits should be handled with care, but they can come in handy.
219+
220+
### On-demand strict floats
221+
222+
Scala.js under-specifies `Float` operations by default, saying that they can sometimes behave as if they were `Double`s.
223+
In 0.6.x, you can configure your application to use *strict-float semantics*, guaranteeing that all `Float` operations behave as on the JVM, with the appropriate truncation of precision (with the notable exception of `.toString()`).
224+
The following sbt setting enables this:
225+
226+
{% highlight scala %}
227+
scalaJSSemantics ~= { _.withStrictFloats(true) }
228+
{% endhighlight %}
229+
230+
Beware that this can have a major impact on performance on VMs that do not support the [`Math.fround`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround) function.
231+
232+
### Obfuscation of class names
233+
234+
The `scalaJSSemantics` option also allows to obfuscate or otherwise rename the class names in the emitted .js file, as was requested in [#1113](https://github.com/scala-js/scala-js/issues/1113).
235+
For example, this sbt setting empties out all class names in the package `my.company`:
236+
237+
{% highlight scala %}
238+
scalaJSSemantics ~= (_.withRuntimeClassName { linkedClass =>
239+
val fullName = linkedClass.fullName
240+
if (fullName.startsWith("my.company.")) ""
241+
else fullName
242+
})
243+
{% endhighlight %}
244+
245+
This changes the value returned by `x.getClass.getName` or `classOf[C].getName`.
246+
247+
### We publish to Maven Central
248+
249+
This should probably not affect sbt users, but it now becomes possible to imagine a Maven plugin for Scala.js.
250+
To this effect, the sbt plugin codebase has also been refactored, and all parts that are not strictly bound to sbt as a build tool have been extracted in Mavenized artifacts.
251+
An enthusiast Maven user could therefore build a Maven plugin with relatively few lines of code.
252+
As a measurable figure, the code specific to sbt contains only 1,686 lines of code.
253+
254+
## Bugfixes
255+
256+
Amongst others, the following bugs have been fixed since 0.5.6:
257+
258+
* [#1430](https://github.com/scala-js/scala-js/issues/1430) `ClassTag.unapply` method (for deconstruction) fails for raw JS classes
259+
* [#1423](https://github.com/scala-js/scala-js/issues/1423) String.getBytes returns trailing zeroes
260+
* [#1324](https://github.com/scala-js/scala-js/issues/1324) Date.parse should return a Double, not an Int
261+
* [#1349](https://github.com/scala-js/scala-js/issues/1349) Auto-completion in runMain task does not work
262+
* [#1192](https://github.com/scala-js/scala-js/issues/1192) hashCode for floating points has a very bad distribution
263+
* [#1402](https://github.com/scala-js/scala-js/issues/1402) `Traversers` does not handle the case of `Debugger`

doc/index.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,21 @@ Generated Scaladocs are available here:
3131

3232
### Scala.js
3333

34+
#### Scala.js 0.6.0-RC1
35+
* [0.6.0-RC1 scalajs-library]({{ BASE_PATH }}/api/scalajs-library/0.6.0-RC1/#scala.scalajs.js.package)
36+
* [0.6.6-RC1 scalajs-test-interface]({{ BASE_PATH }}/api/scalajs-test-interface/0.6.0-RC1/)
37+
* [0.6.0-RC1 scalajs-stubs]({{ BASE_PATH }}/api/scalajs-stubs/0.6.0-RC1/)
38+
* [0.6.0-RC1 scalajs-ir]({{ BASE_PATH }}/api/scalajs-ir/0.6.0-RC1/#org.scalajs.core.ir.package)
39+
* [0.6.0-RC1 scalajs-tools]({{ BASE_PATH }}/api/scalajs-tools/0.6.0-RC1/#org.scalajs.core.tools.package) ([Scala.js version]({{ BASE_PATH }}/api/scalajs-tools-js/0.6.0-RC1/#org.scalajs.core.tools.package))
40+
* [0.6.0-RC1 scalajs-js-envs]({{ BASE_PATH }}/api/scalajs-js-envs/0.6.0-RC1/#org.scalajs.jsenv.package)
41+
* [0.6.0-RC1 scalajs-test-adapter]({{ BASE_PATH }}/api/scalajs-sbt-test-adapter/0.6.0-RC1/#org.scalajs.testadapter.package)
42+
* [0.6.0-RC1 sbt-scalajs]({{ BASE_PATH }}/api/sbt-scalajs/0.6.0-RC1/#org.scalajs.sbtplugin.package)
43+
3444
#### Scala.js 0.6.0-M3
3545
* [0.6.0-M3 scalajs-library]({{ BASE_PATH }}/api/scalajs-library/0.6.0-M3/#scala.scalajs.js.package)
3646
* [0.6.6-M3 scalajs-test-interface]({{ BASE_PATH }}/api/scalajs-test-interface/0.6.0-M3/)
3747
* [0.6.0-M3 scalajs-stubs]({{ BASE_PATH }}/api/scalajs-stubs/0.6.0-M3/)
38-
* [0.6.0-M3 scalajs-ir]({{ BASE_PATH }}/api/scalajs-ir/0.6.0-M2/#org.scalajs.core.ir.package)
48+
* [0.6.0-M3 scalajs-ir]({{ BASE_PATH }}/api/scalajs-ir/0.6.0-M3/#org.scalajs.core.ir.package)
3949
* [0.6.0-M3 scalajs-tools]({{ BASE_PATH }}/api/scalajs-tools/0.6.0-M3/#org.scalajs.core.tools.package) ([Scala.js version]({{ BASE_PATH }}/api/scalajs-tools-js/0.6.0-M3/#org.scalajs.core.tools.package))
4050
* [0.6.0-M3 scalajs-js-envs]({{ BASE_PATH }}/api/scalajs-js-envs/0.6.0-M3/#org.scalajs.jsenv.package)
4151
* [0.6.0-M3 scalajs-test-adapter]({{ BASE_PATH }}/api/scalajs-test-adapter/0.6.0-M3/#org.scalajs.testadapter.package)

downloads.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ We strongly recommend using the SBT plugin, as shown in the [bootstrapping skele
99

1010
The CLI distribution requires `scala` and `scalac` (of the right major version) to be on the execution path. Unpack it wherever you like and add the `bin/` folder to your execution path.
1111

12+
#### Scala.js 0.6.0-RC1
13+
* [0.6.0-RC1, Scala 2.11 (tgz, 20MB)]({{ BASE_PATH }}/files/scalajs_2.11-0.6.0-RC1.tgz)
14+
* [0.6.0-RC1, Scala 2.11 (zip, 20MB)]({{ BASE_PATH }}/files/scalajs_2.11-0.6.0-RC1.zip)
15+
* [0.6.0-RC1, Scala 2.10 (tgz, 18MB)]({{ BASE_PATH }}/files/scalajs_2.10-0.6.0-RC1.tgz)
16+
* [0.6.0-RC1, Scala 2.10 (zip, 18MB)]({{ BASE_PATH }}/files/scalajs_2.10-0.6.0-RC1.zip)
17+
1218
#### Scala.js 0.6.0-M3
1319
* [0.6.0-M3, Scala 2.11 (tgz, 18MB)]({{ BASE_PATH }}/files/scalajs_2.11-0.6.0-M3.tgz)
1420
* [0.6.0-M3, Scala 2.11 (zip, 18MB)]({{ BASE_PATH }}/files/scalajs_2.11-0.6.0-M3.zip)

index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ List of websites using Scala.js:
285285

286286
## Version History
287287

288+
- [0.6.0-RC1](/news/2015/01/12/announcing-scalajs-0.6.0-RC1/)
288289
- [0.6.0-M3](/news/2014/12/22/announcing-scalajs-0.6.0-M3/)
289290
- [0.6.0-M2](/news/2014/12/05/announcing-scalajs-0.6.0-M2/)
290291
- [0.6.0-M1](/news/2014/12/01/announcing-scalajs-0.6.0-M1/)

0 commit comments

Comments
 (0)