|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: Announcing Scala.js 1.7.0 |
| 4 | +category: news |
| 5 | +tags: [releases] |
| 6 | +permalink: /news/2021/08/04/announcing-scalajs-1.7.0/ |
| 7 | +--- |
| 8 | + |
| 9 | + |
| 10 | +We are excited to announce the release of Scala.js 1.7.0! |
| 11 | + |
| 12 | +This release fixes a number of bugs. |
| 13 | +In particular, regular expressions, available through `java.util.regex.Pattern` or Scala's `Regex` and `.r` method, now behave in the same way as on the JVM. |
| 14 | +This change has compatibility implications, which we discuss below. |
| 15 | + |
| 16 | +Moreover, this release fixes *all* the known bugs that were left. |
| 17 | +As of this writing, Scala.js 1.7.0 has zero known bugs! |
| 18 | + |
| 19 | +The Scala standard library was upgraded to versions 2.12.14 and 2.13.6. |
| 20 | + |
| 21 | +Read on for more details. |
| 22 | + |
| 23 | +<!--more--> |
| 24 | + |
| 25 | +## Getting started |
| 26 | + |
| 27 | +If you are new to Scala.js, head over to [the tutorial]({{ BASE_PATH }}/tutorial/). |
| 28 | + |
| 29 | +If you need help with anything related to Scala.js, you may find our community [on Gitter](https://gitter.im/scala-js/scala-js) and [on Stack Overflow](https://stackoverflow.com/questions/tagged/scala.js). |
| 30 | + |
| 31 | +Bug reports can be filed [on GitHub](https://github.com/scala-js/scala-js/issues). |
| 32 | + |
| 33 | +## Release notes |
| 34 | + |
| 35 | +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. |
| 36 | + |
| 37 | +This is a **minor** release: |
| 38 | + |
| 39 | +* It is backward binary compatible with all earlier versions in the 1.x series: libraries compiled with 1.0.x through 1.6.x can be used with 1.7.0 without change. |
| 40 | +* It is *not* forward binary compatible with 1.6.x: libraries compiled with 1.7.0 cannot be used with 1.6.x or earlier. |
| 41 | +* It is *not* entirely backward source compatible: it is not guaranteed that a codebase will compile *as is* when upgrading from 1.6.x (in particular in the presence of `-Xfatal-warnings`). |
| 42 | + |
| 43 | +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. |
| 44 | + |
| 45 | +## Fixes with compatibility concerns |
| 46 | + |
| 47 | +### Regular expressions have been fixed to match the JVM behavior |
| 48 | + |
| 49 | +Until Scala.js 1.6.x, the regular expressions provided by `java.util.regex.Pattern`, and used by `scala.util.matching.Regex` and the `.r` method, were implemented directly in terms of JavaScript's `RegExp`. |
| 50 | +That meant that they used the feature set and the semantics of [JavaScript regular expressions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions), which are different from [Java regular expressions](https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/util/regex/Pattern.html). |
| 51 | +Scala.js 1.7.0 finally fixes this issue, and now correctly implements the semantics of Java regular expressions, although some features are not supported. |
| 52 | + |
| 53 | +Since the old implementation has been there for 7 years, and documented as such, it is possible that this fix will actually break some code in the wild. |
| 54 | +During the implementation of this feature, we have analyzed the corpus of all Scala.js-only libraries (without JVM support) and extracted all the regexes that they use. |
| 55 | +We have verified that none of those use cases are impacted by this change. |
| 56 | +It is still possible that applications are impacted. |
| 57 | + |
| 58 | +It is also possible for some cross-platform libraries to face issues, as we have not covered those. |
| 59 | +Unlike Scala.js-only libraries, we consider it unlikely that they will have issues with the *change of semantics* per se, as they already worked on the JVM, with the new semantics. |
| 60 | + |
| 61 | +The biggest danger would be a cross-library that uses the `MULTILINE` flag (aka `(?m)`). |
| 62 | +Indeed, that feature kind of worked before, but is now rejected at `Pattern.compile()`-time with a `PatternSyntaxException` by default. |
| 63 | +The reason is that to correctly implement the semantics of that flag, we need support for look-behind assertions (`(?<=𝑋)`) in JavaScript's `RegExp`. |
| 64 | +That support was only added in ECMAScript 2018, whereas Scala.js targets ES 2015 by default. |
| 65 | + |
| 66 | +It is possible to change that target with the following setting: |
| 67 | + |
| 68 | +{% highlight scala %} |
| 69 | +scalaJSLinkerConfig ~= (_.withESFeatures(_.withESVersion(ESVersion.ES2018))) |
| 70 | +{% endhighlight %} |
| 71 | + |
| 72 | +**Attention!** While this enables support for the `MULTILINE` flag (among others), it restricts your application to environments that support recent JavaScript features. |
| 73 | +If you maintain a library, this restriction applies to all downstream libraries and applications. |
| 74 | + |
| 75 | +We therefore recommend to try and *avoid* the need for that flag instead. |
| 76 | +We give several strategies on how to do so [on the Regular expressions documentation page]({{ BASE_PATH }}/doc/regular-expressions.html). |
| 77 | +That page also contains many more details on the new support of regular expressions. |
| 78 | + |
| 79 | +## New features |
| 80 | + |
| 81 | +### Add a configurable header comment in generated .js files |
| 82 | + |
| 83 | +Sometimes, it is desirable to add a header comment in the generated .js files. |
| 84 | +This is typically used for license information or any other metadata. |
| 85 | +While it has always been possible to post-process the generated .js files in the build, doing so came at the cost of destroying the source maps. |
| 86 | + |
| 87 | +Scala.js 1.7.0 introduces a new linker configuration, `jsHeader`, to specify a comment to insert at the top of .js files: |
| 88 | + |
| 89 | +{% highlight scala %} |
| 90 | +scalaJSLinkerConfig ~= { |
| 91 | + _.withJSHeader( |
| 92 | + """ |
| 93 | + |/* This is the header, which source maps |
| 94 | + | * take into account. |
| 95 | + | */ |
| 96 | + """.stripMargin.trim() + "\n" |
| 97 | + ) |
| 98 | +} |
| 99 | +{% endhighlight %} |
| 100 | + |
| 101 | +The `jsHeader` must be a combination of valid JavaScript whitespace and/or comments, and must not contain any newline character other than `\n` (the UNIX newline). |
| 102 | +If non-empty, it must end with a new line. |
| 103 | +These restrictions ensure that this feature is not abused to inject arbitrary JavaScript code in the .js file generated by the compiler, potentially compromising the compiler abstractions. |
| 104 | + |
| 105 | +## Miscellaneous |
| 106 | + |
| 107 | +### Allow delegating JS class constructor calls with default params |
| 108 | + |
| 109 | +Until Scala.js 1.6.x, in a JS class, a secondary constructor calling another constructor with default parameters had to specify actual values for all parameters. |
| 110 | +For example, the following code was rejected: |
| 111 | + |
| 112 | +{% highlight scala %} |
| 113 | +class A(x: Int, y: String = "default") extends js.Object { |
| 114 | + def this() = this(12) |
| 115 | +} |
| 116 | +{% endhighlight %} |
| 117 | + |
| 118 | +That restriction has been lifted in Scala.js 1.7.0, so that the above code is now valid. |
| 119 | + |
| 120 | +### New JDK APIs |
| 121 | + |
| 122 | +The following JDK classes have been added |
| 123 | + |
| 124 | +* `java.util.concurrent.atomic.LongAdder` |
| 125 | + |
| 126 | +### Set up the `versionScheme` of library artifacts |
| 127 | + |
| 128 | +This release configures the sbt `versionScheme` setting for the library artifacts of Scala.js (with `"semver-spec"` for the public ones). |
| 129 | +This will reduce spurious eviction warnings in downstream projects. |
| 130 | + |
| 131 | +### Upgrade to GCC v20210601 |
| 132 | + |
| 133 | +We upgraded to the Google Closure Compiler v20210601. |
| 134 | + |
| 135 | +## Bug fixes |
| 136 | + |
| 137 | +Among others, the following bugs have been fixed in 1.7.0: |
| 138 | + |
| 139 | +* [#4507](https://github.com/scala-js/scala-js/issues/4507) 1.6.0 regression: `new mutable.WrappedArrayBuilder(classTag[Unit]).result()` throws a CCE |
| 140 | +* [#3953](https://github.com/scala-js/scala-js/issues/3953) fastOptJS error in scalaz 7.3 with Scala.js 1.0.0 |
| 141 | +* [#3918](https://github.com/scala-js/scala-js/issues/3918) Mixed-in field in class inside lazy val rhs is erroneously immutable in the IR -> IR checking error |
| 142 | +* [#4511](https://github.com/scala-js/scala-js/issues/4511) Nested JS Class in JS Class with Scala companion crashes compiler |
| 143 | +* [#4465](https://github.com/scala-js/scala-js/issues/4465) Default parameters in constructors of nested JS classes cause invalid IR |
| 144 | +* [#4526](https://github.com/scala-js/scala-js/issues/4526) Compiler crashes on nested JS class with default constructor params with private companion |
| 145 | +* [#4469](https://github.com/scala-js/scala-js/issues/4469) Better error message when executing tests with Node missing |
| 146 | +* [#4336](https://github.com/scala-js/scala-js/issues/4336) Failing `<project>/run` can `close()` subsequent runs too early |
| 147 | +* [#105](https://github.com/scala-js/scala-js/issues/105) `String.split(x: Array[Char])` produces bad regexes |
| 148 | + |
| 149 | +You can find the full list [on GitHub](https://github.com/scala-js/scala-js/issues?q=is%3Aissue+milestone%3Av1.7.0+is%3Aclosed). |
0 commit comments