diff --git a/_config.yml b/_config.yml index a3666f3e..2c55853d 100644 --- a/_config.yml +++ b/_config.yml @@ -18,8 +18,8 @@ author : twitter : sjrdoeraene feedburner : feedname -scalaJSVersion: 0.5.6 -scalaJSBinaryVersion: 0.5 +scalaJSVersion: 0.6.0 +scalaJSBinaryVersion: 0.6 # The production_url is only used when full-domain names are needed # such as sitemap.txt diff --git a/_posts/news/2014-06-30-announcing-scalajs-0.5.1.md b/_posts/news/2014-06-30-announcing-scalajs-0.5.1.md index 6d8b9484..d4efd6ea 100644 --- a/_posts/news/2014-06-30-announcing-scalajs-0.5.1.md +++ b/_posts/news/2014-06-30-announcing-scalajs-0.5.1.md @@ -42,7 +42,7 @@ The new sbt setting `jsDependencyFilter` can be used to modify the dependencies jsDependencyFilter := (_.filter(_.resourceName != "jquery.js")) -The above would prevent "jquery.js" from being included by the sbt runners. See [FlatJSDependency]({{ BASE_PATH }}/api/scalajs-tools/0.5.1/#scala.scalajs.tools.jsdep.FlatJSDependency) for fields that you can use. +The above would prevent "jquery.js" from being included by the sbt runners. See [FlatJSDependency]({{ site.production_url }}/api/scalajs-tools/0.5.1/#scala.scalajs.tools.jsdep.FlatJSDependency) for fields that you can use. #### Ordered testing output diff --git a/_posts/news/2014-09-18-announcing-scalajs-0.5.5.md b/_posts/news/2014-09-18-announcing-scalajs-0.5.5.md index bfe13425..499f6cda 100644 --- a/_posts/news/2014-09-18-announcing-scalajs-0.5.5.md +++ b/_posts/news/2014-09-18-announcing-scalajs-0.5.5.md @@ -57,7 +57,7 @@ Note that these conversions apply equally to other Scala collections like `Seq` #### packageJS `packageJS` has been deprecated in favor of `fastOptJS`. -Its providing tasks (`packageExternalDepsJS`, `packageInternalDepsJS` and `packageExportedProductsJS`) have been deprecated without replacement. If such a mechanism is required, [`ScalaJSPackager`]({{ BASE_PATH }}/api/scalajs-tools/0.5.5/#scala.scalajs.tools.packager.ScalaJSPackager) should be used directly. +Its providing tasks (`packageExternalDepsJS`, `packageInternalDepsJS` and `packageExportedProductsJS`) have been deprecated without replacement. If such a mechanism is required, [`ScalaJSPackager`]({{ site.production_url }}/api/scalajs-tools/0.5.5/#scala.scalajs.tools.packager.ScalaJSPackager) should be used directly. #### sbt Task Renamings diff --git a/_posts/news/2014-11-19-announcing-scalajs-0.5.6.md b/_posts/news/2014-11-19-announcing-scalajs-0.5.6.md index 3369e657..76b5b94c 100644 --- a/_posts/news/2014-11-19-announcing-scalajs-0.5.6.md +++ b/_posts/news/2014-11-19-announcing-scalajs-0.5.6.md @@ -40,7 +40,7 @@ The following features of the Java library have been added: Scala.js now supports the [standard charset conversions](https://docs.oracle.com/javase/7/docs/api/index.html?java/nio/charset/StandardCharsets.html) that every JRE supports. You can now pass instances of `Charset` to methods that convert bytes to characters and vice versa. -Note that you should avoid using `Charset.forName` (and methods that take charsets as strings in general), since they will make all `Charset` implementations reachable and hence explode your code size. If you compile on JDK6 (which does not have `StandardCharsets`), you may use [`scala.scalajs.niocharset.StandardCharsets`]({{ BASE_PATH }}/api/scalajs-library/0.5.6/#scala.scalajs.niocharset.StandardCharsets) to retrieve an instance of the desired `Charset`. +Note that you should avoid using `Charset.forName` (and methods that take charsets as strings in general), since they will make all `Charset` implementations reachable and hence explode your code size. If you compile on JDK6 (which does not have `StandardCharsets`), you may use [`scala.scalajs.niocharset.StandardCharsets`]({{ site.production_url }}/api/scalajs-library/0.5.6/#scala.scalajs.niocharset.StandardCharsets) to retrieve an instance of the desired `Charset`. This also allowed to implement `String.getBytes` ([#1087](https://github.com/scala-js/scala-js/issues/1087)). diff --git a/_posts/news/2014-12-05-announcing-scalajs-0.6.0-M2.md b/_posts/news/2014-12-05-announcing-scalajs-0.6.0-M2.md index c4aa6600..79dc8c8f 100644 --- a/_posts/news/2014-12-05-announcing-scalajs-0.6.0-M2.md +++ b/_posts/news/2014-12-05-announcing-scalajs-0.6.0-M2.md @@ -176,7 +176,7 @@ Should you run into trouble, don't hesitate to ask on the mailing list! When writing cross-compiling code, we need to have two separate projects in sbt for the JVM target and the JS target. The new `CrossProject` type, and its `crossProject` builder, helps in defining these pairs of projects in a DRY way. -See the [documentation of `CrossProject`]({{ BASE_PATH }}/api/sbt-scalajs/0.6.0-M2/#org.scalajs.sbtplugin.cross.CrossProject) for more information and examples. +See the [documentation of `CrossProject`]({{ site.production_url }}/api/sbt-scalajs/0.6.0-M2/#org.scalajs.sbtplugin.cross.CrossProject) for more information and examples. ### Faster! diff --git a/_posts/news/2014-12-22-announcing-scalajs-0.6.0-M3.md b/_posts/news/2014-12-22-announcing-scalajs-0.6.0-M3.md index ad882915..bfc9e6d0 100644 --- a/_posts/news/2014-12-22-announcing-scalajs-0.6.0-M3.md +++ b/_posts/news/2014-12-22-announcing-scalajs-0.6.0-M3.md @@ -203,7 +203,7 @@ Should you run into trouble, don't hesitate to ask on the mailing list! When writing cross-compiling code, we need to have two separate projects in sbt for the JVM target and the JS target. The new `CrossProject` type, and its `crossProject` builder, helps in defining these pairs of projects in a DRY way. -See the [documentation of `CrossProject`]({{ BASE_PATH }}/api/sbt-scalajs/0.6.0-M3/#org.scalajs.sbtplugin.cross.CrossProject) for more information and examples. +See the [documentation of `CrossProject`]({{ site.production_url }}/api/sbt-scalajs/0.6.0-M3/#org.scalajs.sbtplugin.cross.CrossProject) for more information and examples. ### Faster! diff --git a/_posts/news/2015-01-12-announcing-scalajs-0.6.0-RC1.md b/_posts/news/2015-01-12-announcing-scalajs-0.6.0-RC1.md index 3914c54a..a59f1406 100644 --- a/_posts/news/2015-01-12-announcing-scalajs-0.6.0-RC1.md +++ b/_posts/news/2015-01-12-announcing-scalajs-0.6.0-RC1.md @@ -195,7 +195,7 @@ Should you run into trouble, don't hesitate to ask on the mailing list! When writing cross-compiling code, we need to have two separate projects in sbt for the JVM target and the JS target. The new `CrossProject` type, and its `crossProject` builder, helps in defining these pairs of projects in a DRY way. -See the [documentation of `CrossProject`]({{ BASE_PATH }}/api/sbt-scalajs/0.6.0-RC1/#org.scalajs.sbtplugin.cross.CrossProject) for more information and examples. +See the [documentation of `CrossProject`]({{ site.production_url }}/api/sbt-scalajs/0.6.0-RC1/#org.scalajs.sbtplugin.cross.CrossProject) for more information and examples. ### Faster! @@ -215,7 +215,7 @@ The title says it all: `js.Array[A]` and `js.Dictionary[A]` receive the entire S ### Implicits to make "writing JavaScript" easier Sometimes, for example when porting existing JavaScript code, we want to just "write JavaScript" inside our Scala.js code. -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. +A new object `js.DynamicImplicits` ([API]({{ site.production_url }}/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. Needless to say, these implicits should be handled with care, but they can come in handy. ### On-demand strict floats diff --git a/_posts/news/2015-01-23-announcing-scalajs-0.6.0-RC2.md b/_posts/news/2015-01-23-announcing-scalajs-0.6.0-RC2.md index 4ade9805..8382c167 100644 --- a/_posts/news/2015-01-23-announcing-scalajs-0.6.0-RC2.md +++ b/_posts/news/2015-01-23-announcing-scalajs-0.6.0-RC2.md @@ -205,7 +205,7 @@ Should you run into trouble, don't hesitate to ask on the mailing list! When writing cross-compiling code, we need to have two separate projects in sbt for the JVM target and the JS target. The new `CrossProject` type, and its `crossProject` builder, helps in defining these pairs of projects in a DRY way. -See the [documentation of `CrossProject`]({{ BASE_PATH }}/api/sbt-scalajs/0.6.0-RC2/#org.scalajs.sbtplugin.cross.CrossProject) for more information and examples. +See the [documentation of `CrossProject`]({{ site.production_url }}/api/sbt-scalajs/0.6.0-RC2/#org.scalajs.sbtplugin.cross.CrossProject) for more information and examples. ### Faster! @@ -225,7 +225,7 @@ The title says it all: `js.Array[A]` and `js.Dictionary[A]` receive the entire S ### Implicits to make "writing JavaScript" easier Sometimes, for example when porting existing JavaScript code, we want to just "write JavaScript" inside our Scala.js code. -A new object `js.DynamicImplicits` ([API]({{ BASE_PATH }}/api/scalajs-library/0.6.0-RC2/#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. +A new object `js.DynamicImplicits` ([API]({{ site.production_url }}/api/scalajs-library/0.6.0-RC2/#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. Needless to say, these implicits should be handled with care, but they can come in handy. ### On-demand strict floats diff --git a/_posts/news/2015-02-05-announcing-scalajs-0.6.0.md b/_posts/news/2015-02-05-announcing-scalajs-0.6.0.md new file mode 100644 index 00000000..6f884150 --- /dev/null +++ b/_posts/news/2015-02-05-announcing-scalajs-0.6.0.md @@ -0,0 +1,296 @@ +--- +layout: post +title: Announcing Scala.js 0.6.0 +category: news +tags: [releases] +--- +{% include JB/setup %} + +We are thrilled to announce the final release of Scala.js 0.6.0! + +As of this version, we do not consider Scala.js to be experimental anymore. +We believe it has reached maturity, and from now on, the language semantics as well as the APIs will only evolve in backward compatible ways, or go through proper deprecation cycles. + +Today is also the 2-year anniversary of Scala.js! +The [first commit](https://github.com/scala-js/scala-js/commit/9ad7627c2418e5d345375705ca087a60e3aa2c22) was pushed on February 5, 2013. + +## Getting started + +If you are new to Scala.js, head over to +[the tutorial]({{ BASE_PATH }}/doc/tutorial.html). + +## Release notes + +As the change in "major" version number witnesses, this release is *not* binary compatible with 0.5.x. +Libraries need to be recompiled and republished using 0.6.0 to be compatible. +More importantly, this release is not source compatible with 0.5.x either. + +Please report any issues [on GitHub](https://github.com/scala-js/scala-js/issues). + +The following libraries have already been upgraded and published for 0.6.0: + +* [DOM types](https://github.com/scala-js/scala-js-dom): `"org.scala-js" %%% "scalajs-dom" % "0.7.0"` +* [jQuery types](https://github.com/scala-js/scala-js-jquery): `"be.doeraene" %%% "scalajs-jquery" % "0.7.0"` +* [Scala.rx](https://github.com/lihaoyi/scala.rx): `"com.lihaoyi" %%% "scalarx" % "0.2.7"` +* [µPickle](https://github.com/lihaoyi/upickle): `"com.lihaoyi" %%% "upickle" % "0.2.6"` +* [Autowire](https://github.com/lihaoyi/autowire): `"com.lihaoyi" %%% "autowire" % "0.2.4"` +* [scalajs-angulate](https://github.com/jokade/scalajs-angulate): `"biz.enef" %%% "scalajs-angulate" % "0.1"` +* [scalajs-angular](https://github.com/greencatsoft/scalajs-angular): `"com.greencatsoft" %%% "scalajs-angular" % "0.3"` +* [scalaz](https://github.com/japgolly/scalaz): `"com.github.inthenow" %%% "scalaz" % "7.1.0-4"` (via [@japgolly](https://github.com/japgolly)) + +The following testing frameworks are available: + +* [µTest](https://github.com/lihaoyi/utest): `"com.lihaoyi" %%% "utest" % "0.3.0" % "test"` +* [MiniTest](https://github.com/monifu/minitest): `"org.monifu" %%% "minitest" % "0.11" % "test"` +* [Greenlight](https://github.com/greencatsoft/greenlight) +* [ScalaCheck](https://github.com/rickynils/scalacheck): `"com.github.inthenow" %%% "scalacheck" % "1.12.2" % "test"` +* [zCheck](https://github.com/InTheNow/zcheck): `"com.github.inthenow" %%% "zcheck" % "0.6.0" % "test"` + +And the following helper sbt plugins as well: + +* [Workbench](https://github.com/lihaoyi/workbench): `addSbtPlugin("com.lihaoyi" % "workbench" % "0.2.3")` +* @InTheNow's [sbt-scalajs](https://github.com/InTheNow/sbt-scalajs): `addSbtPlugin("com.github.inthenow" % "sbt-scalajs" % "0.6.0")` + +There is also a new--and incompatible--version of the DOM API. +We recommend that you first upgrade to 0.7.0 and the above libraries while upgrading to Scala.js 0.6.0. +As a second step, you can upgrade to the DOM API version 0.8.0. +Libraries depending on the DOM API must also be republished against this version of the DOM API, since it is by and large incompatible with 0.7.0. +Here are the 0.8.0 versions of said libraries: + +* [DOM types](https://github.com/scala-js/scala-js-dom): `"org.scala-js" %%% "scalajs-dom" % "0.8.0"` +* [jQuery types](https://github.com/scala-js/scala-js-jquery): `"be.doeraene" %%% "scalajs-jquery" % "0.8.0"` +* [ScalaTags](https://github.com/lihaoyi/scalatags): `"com.lihaoyi" %%% "scalatags" % "0.4.5"` +* [scalajs-angulate](https://github.com/jokade/scalajs-angulate) and [scalajs-angular](https://github.com/greencatsoft/scalajs-angular): not yet published + +To start a Play! project with Scala.js, have a look at [play-with-scalajs-example](https://github.com/vmunier/play-with-scalajs-example). + +## Preparations before upgrading from 0.5.x + +### Upgrade to 0.5.6 if not already done + +Before upgrading to 0.6.0, **we strongly recommend that you upgrade to Scala.js 0.5.6**, and address all deprecation warnings. +Scala.js 0.5.6 contains warnings for the most vicious breaking changes of 0.6.x. + +### Migrate away from the Scala.js Jasmine test framework + +If you use the Jasmine test framework wrapper for Scala.js (`scalajs-jasmine-test-framework`), migrate away from it to one of the other testing frameworks for Scala.js. +The Jasmine test framework wrapper is *not* a good testing framework for Scala.js code, and is being *removed* in 0.6.x. + +Possible replacements: + +* [uTest](https://github.com/lihaoyi/utest) +* [MiniTest](https://github.com/monifu/minitest) +* [Greenlight](https://github.com/greencatsoft/greenlight) +* [otest](https://github.com/cgta/otest) + +Note that these testing frameworks also need to upgrade to 0.6.0 before you can use them. + +## Upgrade to 0.6.0 from 0.5.6 + +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/6ccd5f64c3d46b203685a3c0762142513f5cc3e9), which mostly consists in: + +* Upgrade to sbt >= 0.13.7. +* Adaptations to new groupId and artifact names for Scala.js packages. +* Adaptation to the new `AutoPlugin` infrastructure of the sbt plugin. +* Drop the prefix `ScalaJSKeys.` for Scala.js-specific sbt keys. +* Upgrade to 0.6.0-enabled versions of your dependencies. + +On the sbt command line, not much changes, except the way you use the `fastOpt` and `fullOpt` stages. +In Scala 0.5.x, you could run in the `fastOpt` stage with: + + > fastOptStage::run + +In 0.6.x, the stage is regulated by the setting `scalaJSStage`, which is one of: + +* `PreLinkStage` (default): uses Rhino +* `FastOptStage`: `fastOpt` mode, uses Node.js or PhantomJS +* `FullOptStage`: `fullOpt` mode, uses Node.js or PhantomJS + +You can change it from the command line with + + > set scalaJSStage := FastOptStage + > run # runs in fastOpt mode + +In a multi-project build, you'll want to change it for all projects, which can be done with `in Global`: + + > set scalaJSStage in Global := FastOptStage + +## Major changes + +This section discusses major changes affecting source compatibility, which may or may not apply to your project. + +### `ClassCastException` becomes an undefined behavior + +The JVM, in its incommensurable magnanimity, throws nicely specified exceptions when you do something bad with your code. +For example, it will nicely throw a `ClassCastException` if you perform an invalid `.asInstanceOf`, or an `ArithmeticException` if you divide an integer by 0. + +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. +Until 0.5.x, `ClassCastException`s were properly reported, though. +We have found, however, that checking these buggy cases costs up to 100% overhead to the overall execution time of a Scala.js program. + +In Scala.js 0.6.x, therefore, invalid casts become an undefined behavior as well. +However, the compiler will *still* be nice with you *in the PreLink and FastOpt stages*, by throwing an `UndefinedBehaviorError` if you perform an invalid cast (instead of a `ClassCastException`). +`UndefinedBehaviorError` is a *fatal* error, meaning it won't be caught by `case NonFatal(e)` handlers. +In fullOpt mode, the checks are removed for maximum efficiency. + +You *must not catch* `UndefinedBehaviorError`, since that would cause your program to behave differently in the fullOpt stage than in the other stages. +The idea of `UndefinedBehaviorError` is that you can enjoy strict checks and stack traces while developing. + +If you really want `ClassCastException`s to be thrown reliably (in all stages), you can enable them in your application, at the expense of runtime performance, with the following sbt setting: + +{% highlight scala %} +scalaJSSemantics ~= { _.withAsInstanceOfs( + org.scalajs.core.tools.sem.CheckedBehavior.Compliant) } +{% endhighlight %} + +This applies to the entire application, including dependencies. +There is no way to select parts of the application where this applies, because there is no way to make that sound. + +### The `scala.scalajs.js` package has been simplified + +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: + +* `js.String`, `js.Boolean`, `js.Number` and `js.Undefined` have been removed, as well as their `js.prim.*` equivalent. + `String`, `Boolean`, `Double` and `Unit` should be used instead, respectively. +* `js.parseInt(s)` and `js.parseFloat(s)` should be replaced by `s.toInt` and `s.toDouble`, respectively. +* `js.NaN`, `js.Infinity` should be replaced by `Double.NaN` and `Double.PositiveInfinity`, respectively. +* `js.isNaN(x)` should be replaced by `x.isNaN`. +* `js.isFinite(x)` should be replaced by `!x.isNaN && !x.isInfinite`. + +Methods provided by ECMAScript 5.1 on primitive strings and numbers can be enabled by importing the following implicit conversions: + +{% highlight scala %} +import js.JSStringOps._ +import js.JSNumberOps._ +{% endhighlight %} + +### `js.native` in facade types + +When writing facade types, it was previously recommended to use `???` as a fake body for fields and methods. +You should now use `js.native` instead, as in: + +{% highlight scala %} +trait Foo extends js.Object { + var bar: Int = js.native + def foobar(x: Int): String = js.native +} +{% endhighlight %} + +The compiler will emit a warning if you use any other body. +The warning will become an error in 1.0.0. + +### `@JSExport` exports to fully qualified names by default + +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. +Consider this code: + +{% highlight scala %} +package babar + +@JSExport +class Foo +{% endhighlight %} + +In 0.5.x, `Foo` is exported as `Foo`. +In 0.6.x, it is exported as `babar.Foo` instead. + +### Testing frameworks adaptations + +If you are not a testing framework implementor, this section does not apply to you. +Please follow the migration guidelines of any testing framework you may use. + +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. +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, and severe discrepencies with the JVM sbt testing interface. +Scala.js 0.6.x now supports its JS version of the original sbt testing interface, with all its power, API, and usability features. +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. + +An existing barebone cross-compiling testing framework can be found [in our tests](https://github.com/scala-js/scala-js/tree/v0.6.0/sbt-plugin-test). +Some highlights: + +* [Build definition for the cross-compiling framework](https://github.com/scala-js/scala-js/blob/v0.6.0/sbt-plugin-test/build.sbt#L49-L64) +* [(Cross-compiling) source code of the testing framework](https://github.com/scala-js/scala-js/tree/v0.6.0/sbt-plugin-test/testFramework/src/main/scala/sbttest/framework) +* [Build definition for a cross-compiling project using the framework](https://github.com/scala-js/scala-js/blob/v0.6.0/sbt-plugin-test/build.sbt#L66-L86) +* [Source code of the project using the framework](https://github.com/scala-js/scala-js/tree/v0.6.0/sbt-plugin-test/multiTest) + +Adapting your testing framework to follow this structure is likely to be the easiest path of migration. +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. + +Should you run into trouble, don't hesitate to ask on the mailing list! + +## Enhancements + +### Defining cross-compiling projects with `crossProject` + +When writing cross-compiling code, we need to have two separate projects in sbt for the JVM target and the JS target. +The new `CrossProject` type, and its `crossProject` builder, helps in defining these pairs of projects in a DRY way. + +See the [documentation of `CrossProject`]({{ site.production_url }}/api/sbt-scalajs/0.6.0/#org.scalajs.sbtplugin.cross.CrossProject) for more information and examples. + +### Faster! + +Scala.js 0.6.0 benefits from many performance improvements, most notably: + +* `asInstanceOf`s are unchecked (see above), giving `fullOpt` code up to twice as fast as before +* `Range.foreach`, aka the `for (i <- 0 until n)` kind of loops, is inlined away, giving the same performance as an explicit `while` loop. +* Higher-order operations on `js.Array`s and `js.Dictionary`s (such as `foreach`, `map`, etc.) are inlined away as `while` loops. +* Various improvements to the optimizer. + +### Scala collection API for `js.Array[A]` and `js.Dictionary[A]` + +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]`. + +`js.Array` becomes the default implementation of `mutable.Buffer`, i.e., `mutable.Buffer.empty` returns a `js.Array` wrapped in a `js.WrappedArray`. + +### Implicits to make "writing JavaScript" easier + +Sometimes, for example when porting existing JavaScript code, we want to just "write JavaScript" inside our Scala.js code. +A new object `js.DynamicImplicits` ([API]({{ site.production_url }}/api/scalajs-library/0.6.0/#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. +Needless to say, these implicits should be handled with care, but they can come in handy. + +### On-demand strict floats + +Scala.js under-specifies `Float` operations by default, saying that they can sometimes behave as if they were `Double`s. +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()`). +The following sbt setting enables this: + +{% highlight scala %} +scalaJSSemantics ~= { _.withStrictFloats(true) } +{% endhighlight %} + +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. + +### Obfuscation of class names + +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). +For example, this sbt setting empties out all class names in the package `my.company`: + +{% highlight scala %} +scalaJSSemantics ~= (_.withRuntimeClassName { linkedClass => + val fullName = linkedClass.fullName + if (fullName.startsWith("my.company.")) "" + else fullName +}) +{% endhighlight %} + +This changes the value returned by `x.getClass.getName` or `classOf[C].getName`. + +### We publish to Maven Central + +This should probably not affect sbt users, but it now becomes possible to imagine Maven and Gradle plugins for Scala.js. +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. +An enthusiast Maven/Gradle user could therefore build a Maven/Gradle plugin with relatively few lines of code. +As a measurable figure, the code specific to sbt contains only 1,686 lines of code. + +## Bugfixes + +Amongst others, the following bugs have been fixed since 0.5.6: + +* [#1430](https://github.com/scala-js/scala-js/issues/1430) `ClassTag.unapply` method (for deconstruction) fails for raw JS classes +* [#1423](https://github.com/scala-js/scala-js/issues/1423) String.getBytes returns trailing zeroes +* [#1324](https://github.com/scala-js/scala-js/issues/1324) Date.parse should return a Double, not an Int +* [#1349](https://github.com/scala-js/scala-js/issues/1349) Auto-completion in runMain task does not work +* [#1192](https://github.com/scala-js/scala-js/issues/1192) hashCode for floating points has a very bad distribution +* [#1402](https://github.com/scala-js/scala-js/issues/1402) `Traversers` does not handle the case of `Debugger` +* [#1451](https://github.com/scala-js/scala-js/issues/1451) ScalaDoc run crashes with property `@JSExports` +* [#1455](https://github.com/scala-js/scala-js/issues/1455) Runs for ScalaDoc complain about `@JSExport(SomeFinalVal)` +* [#1458](https://github.com/scala-js/scala-js/issues/1458) PhantomJS 2 expects a scheme name (`file:///`) for all urls, not just a path to local files diff --git a/contribute/index.md b/contribute/index.md deleted file mode 100644 index 146e4efd..00000000 --- a/contribute/index.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -layout: page -title: Contribute -tagline: to Scala.js ---- -{% include JB/setup %} - -Scala.js is a fairly young project. Currently, it has a working core compiler, -and a minimal sbt plugin. But there is a lot more to do, and you can help! - -* Improve this website and the documentation by - [forking it on GitHub](https://github.com/scala-js/scala-js-website) -* [Port the Java library](javalib.html): - expand the port of the Java library written in Scala.js -* Check out the [ideas](https://github.com/scala-js/scala-js/issues?labels=ideas&page=1&state=open) on - the issue tracker for other cool things you could work on, - like [Play! Integration](https://github.com/scala-js/scala-js/issues/188) or a - [Testing Suite](https://github.com/scala-js/scala-js/issues/96) - -If you start seriously on something, make sure to -[mention it on the mailing list](https://groups.google.com/forum/?fromgroups#!forum/scala-js) -to avoid duplicating efforts. - -If you think about something else, come and discuss on the mailing list too! diff --git a/contribute/javalib.md b/contribute/javalib.md deleted file mode 100644 index 29da911e..00000000 --- a/contribute/javalib.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -layout: page -title: Port the Java library ---- -{% include JB/setup %} - -Scala is built on top of Java and its standard library. Therefore, Scala.js -needs some parts of the Java library to work. This port of the Java library -is itself written in Scala.js. - -Currently, only a very small portion is implemented. A very simple, although -sometimes tedious, thing that will help Scala.js is to expand this port. It -basically boils down to - -1. Identifying what classes are needed (either because they are used by the - Scala library, or because their are generally useful) -2. Implement their specification in Scala -3. "Native" methods in Java are typically implemented in Scala.js using the - interoperability with JavaScript. - -For license considerations, this must be a clean room implementation with -respect to most existing implementations. -However, as far as I understand it, the -[Apache Harmony](http://harmony.apache.org/) implementation, although -discontinued since 2011, can be used, since its license is compatible with -the BSD-style license of Scala.js. - -See [the JavaLib subdirectory on GitHub](https://github.com/scala-js/scala-js/tree/master/javalib/src/main/scala/java). diff --git a/doc/calling-javascript.md b/doc/calling-javascript.md index 5b4668f2..4ca90b37 100644 --- a/doc/calling-javascript.md +++ b/doc/calling-javascript.md @@ -13,22 +13,24 @@ Because JavaScript is dynamically typed, it is possible to call JS libraries in a dynamically typed way. However, it is also possible to interop with static types, for better leveraging of Scala. -## Primitive JavaScript types +## Pre-defined JavaScript types -The package `scala.scalajs.js` -([code on GitHub](https://github.com/lampepfl/scala-js/tree/master/library/src/main/scala/scala/scalajs/js)) -contains static type definitions for all the types, functions and variables -that are part of the ECMAScript 5 standard library, including the primitive -types. +Primitive JavaScript types (`number`, `boolean`, `string`, `null` and +`undefined`) are represented by their natural equivalent in Scala, as shown +in the [type equivalence table](./js-interoperability.html#type-correspondance). -The core type hierarchy is as follows: +For other pre-defined JavaScript types, such as arrays and functions, the +package `scala.scalajs.js` +([ScalaDoc]({{ site.production_url }}/api/scalajs-library/{{ site.scalaJSVersion }}/#scala.scalajs.js.package)) +provides dedicated definitions. + +The class hierarchy for these standard types is as follows: js.Any +- js.Object | +- js.Date | +- js.RegExp | +- js.Array[A] - | +- js.Dictionary[A] | +- js.Function | +- js.Function0[+R] | +- js.Function1[-T1, +R] @@ -39,97 +41,56 @@ The core type hierarchy is as follows: | +- js.ThisFunction1[-T0, -T1, +R] | +- ... | +- js.ThisFunction21[-T0, ..., -T21, +R] - +- js.prim.Number - +- js.prim.Boolean - +- js.prim.String - +- js.prim.Undefined - - -Note that the types in the `prim` package should not directly be used, -since they have a direct correspondance in Scala (see the -[interoperability](./js-interoperability.html) page). The reason they -exist is that for example a `scala.Double` can be stored in a variable -of type `js.Any` (through implicit conversion to `js.prim.Number`). - -A value of any of these types is encoded as is in JavaScript, without wrapping. -Even when such a value is assigned to a `val` of type `scala.Any` or of a -generic type, there is no boxing. E.g., a `js.Array[js.Date]` is a JavaScript -`Array` which contains JavaScript `Date`'s at runtime. - -These types have all the fields and methods available in the JavaScript API. - -There are implicit conversions from corresponding Scala types and back: - -
| Scala type | JavaScript type |
|---|---|
| Byte Short Int Long Float Double | js.prim.Number |
| (from js.prim.Number to Double only) | |
| Boolean | js.prim.Boolean |
| java.lang.String | js.prim.String |
| Unit | js.prim.Undefined |
| Array[A] | js.Array[A] |
| FunctionN[T1, ..., TN, R] | js.FunctionN[T1, ..., TN, R] |
| js.ThisFunction{N-1}[T1, ..., TN, R] | |
val definitions.
diff --git a/doc/tutorial.md b/doc/tutorial.md
index 95b1175b..2bd49fbd 100644
--- a/doc/tutorial.md
+++ b/doc/tutorial.md
@@ -18,38 +18,34 @@ First create a new folder where your sbt project will go.
To setup Scala.js in a new sbt project, we need to do two things:
-1. Add the Scala.js sbt plugin
-2. Apply the Scala.js specific settings to the project
+1. Add the Scala.js sbt plugin to the build
+2. Enable the plugin in the project
Adding the Scala.js sbt plugin is a one-liner in `project/plugins.sbt` (all file names we write in this tutorial are relative to the project root):
{% highlight scala %}
-addSbtPlugin("org.scala-lang.modules.scalajs" % "scalajs-sbt-plugin" % "{{ site.scalaJSVersion }}")
+addSbtPlugin("org.scala-js" % "sbt-scalajs" % "{{ site.scalaJSVersion }}")
{% endhighlight %}
-We also setup basic project settings and Scala.js settings in the sbt build file (`build.sbt`, in the project root directory):
+We also setup basic project settings and enable this plugin in the sbt build file (`build.sbt`, in the project root directory):
{% highlight scala %}
-scalaJSSettings
+enablePlugins(ScalaJSPlugin)
name := "Scala.js Tutorial"
-scalaVersion := "2.11.2"
+scalaVersion := "2.11.5" // or any other Scala version >= 2.10.2
{% endhighlight %}
-Last, we need a `project/build.properties` to specify the sbt version:
+Last, we need a `project/build.properties` to specify the sbt version (>= 0.13.7):
{% highlight scala %}
-sbt.version=0.13.5
+sbt.version=0.13.7
{% endhighlight %}
That is all we need to configure the build.
-If at this point you prefer to use Eclipse or IDEA as your IDE, you may use [sbteclipse](https://github.com/typesafehub/sbteclipse/wiki/Using-sbteclipse) or [sbt-idea](https://github.com/mpeltonen/sbt-idea) project files for the IDE. Note that for compiling and running your application, you will still need to use sbt from the command line.
-
-#### Alternative versions
-
-You may instead use 2.10.2, 2.10.3, 2.10.4, 2.11.0 or 2.11.1 for `scalaVersion` if you so wish. Similarly, any 0.13.x version of sbt should work without itch, for example 0.13.5.
+If at this point you prefer to use Eclipse or IDEA as your IDE, you may use [sbteclipse](https://github.com/typesafehub/sbteclipse/wiki/Using-sbteclipse) to generate an Eclipse project, or import the sbt build from IDEA. Note that for compiling and running your application, you will still need to use sbt from the command line.
### HelloWorld application
@@ -78,17 +74,52 @@ As you expect, this will simply print "HelloWorld" when run. To run this, simply
**Troubleshooting**: Should you experience errors with the `PermGen` size of the JVM at this point, you can increase it. Refer, for example, to [this StackOverflow question](http://stackoverflow.com/questions/8331135/transient-outofmemoryerror-when-compiling-scala-classes).
-Congratulations! You have successfully compiled and run your first Scala.js application. The code is actually run by a JavaScript interpreter. If you do not believe this (it happens to us occasionally), you can use sbt's `last`:
+Congratulations! You have successfully compiled and run your first Scala.js application. The code is actually run by a JavaScript interpreter. If you do not believe this (it happens to us occasionally), you can use the `last` command in sbt:
> last
(...)
[info] Running tutorial.webapp.TutorialApp
- [debug] with JSEnv of type class scala.scalajs.sbtplugin.env.rhino.RhinoJSEnv
- [debug] with classpath of type class scala.scalajs.tools.classpath.CompleteIRClasspath
+ [debug] with JSEnv of type class org.scalajs.jsenv.rhino.RhinoJSEnv
+ [debug] with classpath of type class org.scalajs.core.tools.classpath.IRClasspath
[success] (...)
So your code has actually been executed by the [Rhino](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Rhino) JavaScript interpreter.
+### Run with Node.js (optional, but recommended)
+
+Rhino is cool because it runs out of the box, without having to install anything.
+But it is *terribly* slow.
+In general, you do not want to use it for your day-to-day development.
+
+[Node.js](http://nodejs.org/) is a much more performant JavaScript engine.
+To run your code with Node.js, you need to install it, and enable
+`FastOptStage` in sbt using this command:
+
+ > set scalaJSStage in Global := FastOptStage
+ > run
+ [info] Fast optimizing C:\Users\Sepi\Documents\Projets\scalajs-tutorial\target\scala-2.11\scala-js-tutorial-fastopt.js
+ [info] Running tutorial.webapp.TutorialApp
+ Hello world!
+ [success] (...)
+
+The `last` command now shows that this was run with Node.js:
+
+ > last
+ (...)
+ [info] Running tutorial.webapp.TutorialApp
+ [debug] with JSEnv of type class org.scalajs.jsenv.nodejs.NodeJSEnv
+ [debug] with classpath of type class org.scalajs.core.tools.classpath.LinkedClasspath
+ [success] (...)
+
+The stage needs to be set once per sbt session.
+Alternatively, you can include the setting directly in your `build.sbt`, or,
+in order not to disturb your teammates, in a separate `.sbt` file (say,
+`local.sbt`):
+
+ scalaJSStage in Global := FastOptStage
+
+This will enable the fastOpt stage by default when launching sbt.
+
## Step 2: Integrating with HTML
Now that we have a simple JavaScript application, we would like to use it in an HTML page. To do this, we need two steps:
@@ -106,9 +137,11 @@ To generate a single JavaScript file using sbt, just use the `fastOptJS` task:
This will perform some fast optimizations and generate the `target/scala-2.11/scala-js-tutorial-fastopt.js` file containing the JavaScript code.
+(It is possible that the `[info]` does not appear, if you have just run the program in fastOpt mode.)
+
### Create the HTML Page
-To load and launch the created JavaScript, you will need an HTML file. Create the file `scalajs-tutorial-fastopt.html` (or whatever name you prefer, for example `index-fastopt.html`) in the project root with the following content. We will go in the details right after.
+To load and launch the created JavaScript, you will need an HTML file. Create the file `scalajs-tutorial-fastopt.html` (or whatever name you prefer, for example `index-dev.html`) in the project root with the following content. We will go in the details right after.
{% highlight html %}
@@ -138,14 +171,15 @@ If you now open the newly created HTML page in your favorite browser, you will s
## Step 3: Using the DOM
-As the last step has shown, running JavaScript inside a HTML page is not particularly useful if you cannot interact with the page. JavaScript provides the DOM API to interact with the page.
+As the last step has shown, running JavaScript inside an HTML page is not particularly useful if you cannot interact with the page.
+That's what the DOM API is for.
### Adding the DOM Library
To use the DOM, it is best to use the statically typed Scala.js DOM library. To add it to your sbt project, add the following line to your `build.sbt`:
{% highlight scala %}
- libraryDependencies += "org.scala-lang.modules.scalajs" %%% "scalajs-dom" % "0.6"
+libraryDependencies += "org.scala-js" %%% "scalajs-dom" % "0.8.0"
{% endhighlight %}
sbt-savvy folks will notice the `%%%` instead of the usual `%%`. It means we are using a Scala.js library and not a normal Scala library. Have a look at the [Depending on Libraries](./sbt/depending.html) guide for details. Don't forget to reload the build file if sbt is still running:
@@ -168,7 +202,8 @@ import org.scalajs.dom
import dom.document
{% endhighlight %}
-`dom` is the root of the JavaScript DOM and corresponds to the `window` object in JavaScript. We additionally import `document` (which corresponds to `document` in JavaScript) for convenience.
+`dom` is the root of the JavaScript DOM and corresponds to the global scope of Script (aka the `window` object).
+We additionally import `document` (which corresponds to `document` in JavaScript) for convenience.
We now create a method that allows us to append a `` tag with a given text to a given node: @@ -223,7 +258,7 @@ def addClickedMessage(): Unit = { } {% endhighlight %} -You will notice the `@JSExport` annotation. It tells the Scala.js compiler to make a method callable from JavaScript. We must also import this annotation: +You will notice the `@JSExport` annotation. It tells the Scala.js compiler to make that method callable from JavaScript. We must also import this annotation: {% highlight scala %} import scala.scalajs.js.annotation.JSExport @@ -245,10 +280,10 @@ Larger web applications have a tendency to set up reactions to events in JavaScr ### Depending on jQuery -Just like for the DOM, there is a typed library for jQuery, especially packaged for Scala.js. Replace the `libraryDependencies += ...` line in your `build.sbt` by: +Just like for the DOM, there is a typed library for jQuery available in Scala.js. Replace the `libraryDependencies += ...` line in your `build.sbt` by: {% highlight scala %} - libraryDependencies += "org.scala-lang.modules.scalajs" %%% "scalajs-jquery" % "0.6" +libraryDependencies += "be.doeraene" %%% "scalajs-jquery" % "0.8.0" {% endhighlight %} Since we won't be using the DOM directly, we don't need the old library anymore. Note that the jQuery library internally depends on the DOM, but we don't have to care about this. sbt takes care of it automatically. @@ -289,16 +324,14 @@ An option is to include `jquery.js` from an external source, such as [jsDelivr]( {% endhighlight %} -This can easily become very cumbersome, if you depend on multiple libraries. The Scala.js sbt plugin provides a mechanism for libraries to declare the plain JavaScript libraries they depend on and bundle them in single file. All you have to do is activate this and then include the file. +This can easily become very cumbersome, if you depend on multiple libraries. The Scala.js sbt plugin provides a mechanism for libraries to declare the plain JavaScript libraries they depend on and bundle them in a single file. All you have to do is activate this and then include the file. In your `build.sbt`, set: {% highlight scala %} - skip in ScalaJSKeys.packageJSDependencies := false +skip in packageJSDependencies := false {% endhighlight %} -As an alternative to prefixing with `ScalaJSKeys`, you may import all its members (`import ScalaJSKeys._`). Most of the documentation omits the `ScalaJSKeys` prefix for brevity. - After reloading and rerunning `fastOptJS`, this will create `scala-js-tutorial-jsdeps.js` containing all JavaScript libraries next to the main JavaScript file. We can then simply include this file and don't need to worry about JavaScript libraries anymore: {% highlight html %} @@ -333,7 +366,8 @@ We now have an application whose UI is completely setup from within Scala.js. Th ## Step 6: Testing -In this section we will show how such an application can be tested using [uTest](http://github.com/lihaoyi/utest), a tiny testing framework which compiles to both Scala.js and Scala JVM. As a note aside, this framework is also a good choice to test libraries that cross compile. See our [cross compiliation guide](./sbt/cross-building.html) for details. +In this section we will show how such an application can be tested using [uTest](http://github.com/lihaoyi/utest), a tiny testing framework which compiles to both Scala.js and Scala JVM. +As a note aside, this framework is also a good choice to test libraries that cross compile. See our [cross compilation guide](./sbt/cross-building.html) for details. ### Supporting the DOM @@ -347,55 +381,34 @@ Before we start writing tests which we will be able to run through the sbt conso [error] (compile:run) Exception while running JS code: ReferenceError: "window" is not defined. (/home/ts/.ivy2/cache/org.webjars/jquery/jars/jquery-1.10.2.jar#META-INF/resources/webjars/jquery/1.10.2/jquery.js#14) [error] (...) -What basically happens here, is that jQuery (yes, it is included automatically) tries to access the `window` object of the DOM, which doesn't exist by default in the Rhino runner. To make the DOM available in Rhino, add the following to your `build.sbt`: +What basically happens here is that jQuery (yes, it is included automatically) tries to access the `window` object of the DOM, which doesn't exist by default in the Rhino and Node.js runners. +To make the DOM available, add the following to your `build.sbt`: {% highlight scala %} -ScalaJSKeys.jsDependencies += scala.scalajs.sbtplugin.RuntimeDOM +jsDependencies += RuntimeDOM {% endhighlight %} +If you use the fastOpt stage, this will switch to running your code with [PhantomJS](http://phantomjs.org/) instead of Node.js, which you need to install. +Otherwise, in Rhino, a fake DOM is automatically made available. + After reloading, you can invoke `run` successfully: > run [info] Running tutorial.webapp.TutorialApp [success] (...) -Just like other library dependencies, this setting applies transitively: if you depend on a library that depends on the DOM, the you depend on the DOM as well. - -### Running with Node.js or PhantomJS - -This step is optional and requires installing PhantomJS. You may skip it if you like. - -You can run your Scala.js code after the fast-optimization stage using [Node.js](http://nodejs.org/) or [PhantomJS](http://phantomjs.org/). The sbt plugin defaults to Node.js and only runs PhantomJS if the project depends on `RuntimeDOM`. Note that you need to install Node.js and/or PhantomJS separately for this to work (also see the note about running [Node.js on Ubuntu](./sbt/js-envs.html#node-on-ubuntu)). - -After installing [PhantomJS](http://phantomjs.org/), you can invoke: - - > fastOptStage::run - [info] Running tutorial.webapp.TutorialApp - [success] (...) - -If you remember the `last` command from the beginning, you can use it to check that we are actually running PhantomJS: - - > last - (...) - [debug] with JSEnv of type class scala.scalajs.sbtplugin.env.phantomjs.PhantomJSEnv - [debug] with classpath of type class scala.scalajs.tools.classpath.CompleteCIClasspath$SimpleCompleteCIClasspath - [debug] PhantomJS using webpage launcher at: /tmp/phantomjs-launcher-webpage2065180431563237581.html - [success] (...) - -This even shows you the temporary webpage the plugin generates to launch PhantomJS. This can be useful for debugging. +Just like other library dependencies, this setting applies transitively: if you depend on a library that depends on the DOM, then you depend on the DOM as well. ### Adding uTest -According to the [explanation in uTest's readme](http://github.com/lihaoyi/utest#scalajs-and-sbt), we add the following to our `build.sbt`: +Using a testing framework in Scala.js is not much different than on the JVM. +It typically boils down to two sbt settings in the `build.sbt` file. +For uTest, these are: {% highlight scala %} -utest.jsrunner.Plugin.utestJsSettings -{% endhighlight %} +libraryDependencies += "com.lihaoyi" %%% "utest" % "0.2.5" % "test" -And the following to our `project/plugins.sbt`: - -{% highlight scala %} -addSbtPlugin("com.lihaoyi" % "utest-js-plugin" % "0.2.3") +testFrameworks += new TestFramework("utest.runner.Framework") {% endhighlight %} We are now ready to add a first simple test suite (`src/test/scala/tutorial/webapp/TutorialTest.scala`): @@ -438,11 +451,12 @@ To run this test, simply invoke the `test` task: [info] Failed: 0 [success] (...) -We have successfully created a simple test. Note that just like for `run`, you can run `fastOptStage::test`. Of course you'll need PhantomJS installed. It is possible that you see some warnings from the fast-optimizer, these come from uTest: It references Java classes which do not exist in Scala.js (mainly concurrency related). +We have successfully created a simple test. +Just like `run`, the `test` task uses Rhino by default, or Node.js/PhantomJS in fastOpt stage. ### A more complex test -We also would like to test the functionality of our button. For this we face another small issue: The button doesn't exist when testing, since the tests start with an empty DOM tree. To solve this, we create the button in the `setupUI` method and remove it from the HTML: +We also would like to test the functionality of our button. For this we face another small issue: the button doesn't exist when testing, since the tests start with an empty DOM tree. To solve this, we create the button in the `setupUI` method and remove it from the HTML: {% highlight scala %} jQuery("""""") @@ -505,16 +519,17 @@ Size is critical for JavaScript code on the web. To compress the compiled code e [info] Closure: 0 error(s), 0 warning(s) [success] (...) -Note that this can take a while on a larger project (tens of seconds) we do therefore not recommend to use `fullOptJS` during development. If you have used the `fastOptStage` before, there is an equivalent `fullOptStage` to run code after full optimization. +Note that this can take a while on a larger project (tens of seconds), which is why we typically don't use `fullOptJS` during development, but `fastOptJS` instead. +If you have used the `FastOptStage` before, there is a corresponding `FullOptStage` to run code after full optimization. ### Automatically Creating a Launcher Before creating another HTML file which includes the fully optimized JavaScript, we are going to introduce another feature of the sbt plugin. Since the sbt plugin is able to detect the `JSApp` object of the application, there is no need to repeat this in the HTML file. If you add the following setting to your `build.sbt`, sbt will create a `scala-js-tutorial-launcher.js` file which calls the main method: {% highlight scala %} - ScalaJSKeys.persistLauncher in Compile := true +persistLauncher in Compile := true - ScalaJSKeys.persistLauncher in Test := false +persistLauncher in Test := false {% endhighlight %} We set `persistLauncher` to false for testing, since we do not have an application to run. In our HTML page, we can now include this file instead of the manual launcher: diff --git a/downloads.md b/downloads.md index 409a2e70..fcbf0381 100644 --- a/downloads.md +++ b/downloads.md @@ -9,74 +9,80 @@ We strongly recommend using the SBT plugin, as shown in the [bootstrapping skele 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. +#### Scala.js 0.6.0 +* [0.6.0, Scala 2.11 (tgz, 20MB)]({{ site.production_url }}/files/scalajs_2.11-0.6.0.tgz) +* [0.6.0, Scala 2.11 (zip, 20MB)]({{ site.production_url }}/files/scalajs_2.11-0.6.0.zip) +* [0.6.0, Scala 2.10 (tgz, 18MB)]({{ site.production_url }}/files/scalajs_2.10-0.6.0.tgz) +* [0.6.0, Scala 2.10 (zip, 18MB)]({{ site.production_url }}/files/scalajs_2.10-0.6.0.zip) + #### Scala.js 0.6.0-RC2 -* [0.6.0-RC2, Scala 2.11 (tgz, 20MB)]({{ BASE_PATH }}/files/scalajs_2.11-0.6.0-RC2.tgz) -* [0.6.0-RC2, Scala 2.11 (zip, 20MB)]({{ BASE_PATH }}/files/scalajs_2.11-0.6.0-RC2.zip) -* [0.6.0-RC2, Scala 2.10 (tgz, 18MB)]({{ BASE_PATH }}/files/scalajs_2.10-0.6.0-RC2.tgz) -* [0.6.0-RC2, Scala 2.10 (zip, 18MB)]({{ BASE_PATH }}/files/scalajs_2.10-0.6.0-RC2.zip) +* [0.6.0-RC2, Scala 2.11 (tgz, 20MB)]({{ site.production_url }}/files/scalajs_2.11-0.6.0-RC2.tgz) +* [0.6.0-RC2, Scala 2.11 (zip, 20MB)]({{ site.production_url }}/files/scalajs_2.11-0.6.0-RC2.zip) +* [0.6.0-RC2, Scala 2.10 (tgz, 18MB)]({{ site.production_url }}/files/scalajs_2.10-0.6.0-RC2.tgz) +* [0.6.0-RC2, Scala 2.10 (zip, 18MB)]({{ site.production_url }}/files/scalajs_2.10-0.6.0-RC2.zip) #### Scala.js 0.6.0-RC1 -* [0.6.0-RC1, Scala 2.11 (tgz, 20MB)]({{ BASE_PATH }}/files/scalajs_2.11-0.6.0-RC1.tgz) -* [0.6.0-RC1, Scala 2.11 (zip, 20MB)]({{ BASE_PATH }}/files/scalajs_2.11-0.6.0-RC1.zip) -* [0.6.0-RC1, Scala 2.10 (tgz, 18MB)]({{ BASE_PATH }}/files/scalajs_2.10-0.6.0-RC1.tgz) -* [0.6.0-RC1, Scala 2.10 (zip, 18MB)]({{ BASE_PATH }}/files/scalajs_2.10-0.6.0-RC1.zip) +* [0.6.0-RC1, Scala 2.11 (tgz, 20MB)]({{ site.production_url }}/files/scalajs_2.11-0.6.0-RC1.tgz) +* [0.6.0-RC1, Scala 2.11 (zip, 20MB)]({{ site.production_url }}/files/scalajs_2.11-0.6.0-RC1.zip) +* [0.6.0-RC1, Scala 2.10 (tgz, 18MB)]({{ site.production_url }}/files/scalajs_2.10-0.6.0-RC1.tgz) +* [0.6.0-RC1, Scala 2.10 (zip, 18MB)]({{ site.production_url }}/files/scalajs_2.10-0.6.0-RC1.zip) #### Scala.js 0.6.0-M3 -* [0.6.0-M3, Scala 2.11 (tgz, 18MB)]({{ BASE_PATH }}/files/scalajs_2.11-0.6.0-M3.tgz) -* [0.6.0-M3, Scala 2.11 (zip, 18MB)]({{ BASE_PATH }}/files/scalajs_2.11-0.6.0-M3.zip) -* [0.6.0-M3, Scala 2.10 (tgz, 18MB)]({{ BASE_PATH }}/files/scalajs_2.10-0.6.0-M3.tgz) -* [0.6.0-M3, Scala 2.10 (zip, 18MB)]({{ BASE_PATH }}/files/scalajs_2.10-0.6.0-M3.zip) +* [0.6.0-M3, Scala 2.11 (tgz, 18MB)]({{ site.production_url }}/files/scalajs_2.11-0.6.0-M3.tgz) +* [0.6.0-M3, Scala 2.11 (zip, 18MB)]({{ site.production_url }}/files/scalajs_2.11-0.6.0-M3.zip) +* [0.6.0-M3, Scala 2.10 (tgz, 18MB)]({{ site.production_url }}/files/scalajs_2.10-0.6.0-M3.tgz) +* [0.6.0-M3, Scala 2.10 (zip, 18MB)]({{ site.production_url }}/files/scalajs_2.10-0.6.0-M3.zip) #### Scala.js 0.6.0-M2 -* [0.6.0-M2, Scala 2.11 (tgz, 18MB)]({{ BASE_PATH }}/files/scalajs_2.11-0.6.0-M2.tgz) -* [0.6.0-M2, Scala 2.11 (zip, 18MB)]({{ BASE_PATH }}/files/scalajs_2.11-0.6.0-M2.zip) -* [0.6.0-M2, Scala 2.10 (tgz, 18MB)]({{ BASE_PATH }}/files/scalajs_2.10-0.6.0-M2.tgz) -* [0.6.0-M2, Scala 2.10 (zip, 18MB)]({{ BASE_PATH }}/files/scalajs_2.10-0.6.0-M2.zip) +* [0.6.0-M2, Scala 2.11 (tgz, 18MB)]({{ site.production_url }}/files/scalajs_2.11-0.6.0-M2.tgz) +* [0.6.0-M2, Scala 2.11 (zip, 18MB)]({{ site.production_url }}/files/scalajs_2.11-0.6.0-M2.zip) +* [0.6.0-M2, Scala 2.10 (tgz, 18MB)]({{ site.production_url }}/files/scalajs_2.10-0.6.0-M2.tgz) +* [0.6.0-M2, Scala 2.10 (zip, 18MB)]({{ site.production_url }}/files/scalajs_2.10-0.6.0-M2.zip) #### Scala.js 0.6.0-M1 -* [0.6.0-M1, Scala 2.11 (tgz, 18MB)]({{ BASE_PATH }}/files/scalajs_2.11-0.6.0-M1.tgz) -* [0.6.0-M1, Scala 2.11 (zip, 18MB)]({{ BASE_PATH }}/files/scalajs_2.11-0.6.0-M1.zip) -* [0.6.0-M1, Scala 2.10 (tgz, 18MB)]({{ BASE_PATH }}/files/scalajs_2.10-0.6.0-M1.tgz) -* [0.6.0-M1, Scala 2.10 (zip, 18MB)]({{ BASE_PATH }}/files/scalajs_2.10-0.6.0-M1.zip) +* [0.6.0-M1, Scala 2.11 (tgz, 18MB)]({{ site.production_url }}/files/scalajs_2.11-0.6.0-M1.tgz) +* [0.6.0-M1, Scala 2.11 (zip, 18MB)]({{ site.production_url }}/files/scalajs_2.11-0.6.0-M1.zip) +* [0.6.0-M1, Scala 2.10 (tgz, 18MB)]({{ site.production_url }}/files/scalajs_2.10-0.6.0-M1.tgz) +* [0.6.0-M1, Scala 2.10 (zip, 18MB)]({{ site.production_url }}/files/scalajs_2.10-0.6.0-M1.zip) #### Scala.js 0.5.6 -* [0.5.6, Scala 2.11 (tgz, 17MB)]({{ BASE_PATH }}/files/scalajs_2.11-0.5.6.tgz) -* [0.5.6, Scala 2.11 (zip, 17MB)]({{ BASE_PATH }}/files/scalajs_2.11-0.5.6.zip) -* [0.5.6, Scala 2.10 (tgz, 16MB)]({{ BASE_PATH }}/files/scalajs_2.10-0.5.6.tgz) -* [0.5.6, Scala 2.10 (zip, 16MB)]({{ BASE_PATH }}/files/scalajs_2.10-0.5.6.zip) +* [0.5.6, Scala 2.11 (tgz, 17MB)]({{ site.production_url }}/files/scalajs_2.11-0.5.6.tgz) +* [0.5.6, Scala 2.11 (zip, 17MB)]({{ site.production_url }}/files/scalajs_2.11-0.5.6.zip) +* [0.5.6, Scala 2.10 (tgz, 16MB)]({{ site.production_url }}/files/scalajs_2.10-0.5.6.tgz) +* [0.5.6, Scala 2.10 (zip, 16MB)]({{ site.production_url }}/files/scalajs_2.10-0.5.6.zip) #### Scala.js 0.5.5 -* [0.5.5, Scala 2.11 (tgz, 15MB)]({{ BASE_PATH }}/files/scalajs_2.11-0.5.5.tgz) -* [0.5.5, Scala 2.11 (zip, 15MB)]({{ BASE_PATH }}/files/scalajs_2.11-0.5.5.zip) -* [0.5.5, Scala 2.10 (tgz, 16MB)]({{ BASE_PATH }}/files/scalajs_2.10-0.5.5.tgz) -* [0.5.5, Scala 2.10 (zip, 16MB)]({{ BASE_PATH }}/files/scalajs_2.10-0.5.5.zip) +* [0.5.5, Scala 2.11 (tgz, 15MB)]({{ site.production_url }}/files/scalajs_2.11-0.5.5.tgz) +* [0.5.5, Scala 2.11 (zip, 15MB)]({{ site.production_url }}/files/scalajs_2.11-0.5.5.zip) +* [0.5.5, Scala 2.10 (tgz, 16MB)]({{ site.production_url }}/files/scalajs_2.10-0.5.5.tgz) +* [0.5.5, Scala 2.10 (zip, 16MB)]({{ site.production_url }}/files/scalajs_2.10-0.5.5.zip) #### Scala.js 0.5.4 -* [0.5.4, Scala 2.11 (tgz, 15MB)]({{ BASE_PATH }}/files/scalajs_2.11-0.5.4.tgz) -* [0.5.4, Scala 2.11 (zip, 15MB)]({{ BASE_PATH }}/files/scalajs_2.11-0.5.4.zip) -* [0.5.4, Scala 2.10 (tgz, 16MB)]({{ BASE_PATH }}/files/scalajs_2.10-0.5.4.tgz) -* [0.5.4, Scala 2.10 (zip, 16MB)]({{ BASE_PATH }}/files/scalajs_2.10-0.5.4.zip) +* [0.5.4, Scala 2.11 (tgz, 15MB)]({{ site.production_url }}/files/scalajs_2.11-0.5.4.tgz) +* [0.5.4, Scala 2.11 (zip, 15MB)]({{ site.production_url }}/files/scalajs_2.11-0.5.4.zip) +* [0.5.4, Scala 2.10 (tgz, 16MB)]({{ site.production_url }}/files/scalajs_2.10-0.5.4.tgz) +* [0.5.4, Scala 2.10 (zip, 16MB)]({{ site.production_url }}/files/scalajs_2.10-0.5.4.zip) #### Scala.js 0.5.3 -* [0.5.3, Scala 2.11 (tgz, 15MB)]({{ BASE_PATH }}/files/scalajs_2.11-0.5.3.tgz) -* [0.5.3, Scala 2.11 (zip, 15MB)]({{ BASE_PATH }}/files/scalajs_2.11-0.5.3.zip) -* [0.5.3, Scala 2.10 (tgz, 16MB)]({{ BASE_PATH }}/files/scalajs_2.10-0.5.3.tgz) -* [0.5.3, Scala 2.10 (zip, 16MB)]({{ BASE_PATH }}/files/scalajs_2.10-0.5.3.zip) +* [0.5.3, Scala 2.11 (tgz, 15MB)]({{ site.production_url }}/files/scalajs_2.11-0.5.3.tgz) +* [0.5.3, Scala 2.11 (zip, 15MB)]({{ site.production_url }}/files/scalajs_2.11-0.5.3.zip) +* [0.5.3, Scala 2.10 (tgz, 16MB)]({{ site.production_url }}/files/scalajs_2.10-0.5.3.tgz) +* [0.5.3, Scala 2.10 (zip, 16MB)]({{ site.production_url }}/files/scalajs_2.10-0.5.3.zip) #### Scala.js 0.5.2 -* [0.5.2, Scala 2.11 (tgz, 14MB)]({{ BASE_PATH }}/files/scalajs_2.11-0.5.2.tgz) -* [0.5.2, Scala 2.11 (zip, 14MB)]({{ BASE_PATH }}/files/scalajs_2.11-0.5.2.zip) -* [0.5.2, Scala 2.10 (tgz, 15MB)]({{ BASE_PATH }}/files/scalajs_2.10-0.5.2.tgz) -* [0.5.2, Scala 2.10 (zip, 15MB)]({{ BASE_PATH }}/files/scalajs_2.10-0.5.2.zip) +* [0.5.2, Scala 2.11 (tgz, 14MB)]({{ site.production_url }}/files/scalajs_2.11-0.5.2.tgz) +* [0.5.2, Scala 2.11 (zip, 14MB)]({{ site.production_url }}/files/scalajs_2.11-0.5.2.zip) +* [0.5.2, Scala 2.10 (tgz, 15MB)]({{ site.production_url }}/files/scalajs_2.10-0.5.2.tgz) +* [0.5.2, Scala 2.10 (zip, 15MB)]({{ site.production_url }}/files/scalajs_2.10-0.5.2.zip) #### Scala.js 0.5.1 -* [0.5.1, Scala 2.11 (tgz, 13MB)]({{ BASE_PATH }}/files/scalajs_2.11-0.5.1.tgz) -* [0.5.1, Scala 2.11 (zip, 13MB)]({{ BASE_PATH }}/files/scalajs_2.11-0.5.1.zip) -* [0.5.1, Scala 2.10 (tgz, 15MB)]({{ BASE_PATH }}/files/scalajs_2.10-0.5.1.tgz) -* [0.5.1, Scala 2.10 (zip, 15MB)]({{ BASE_PATH }}/files/scalajs_2.10-0.5.1.zip) +* [0.5.1, Scala 2.11 (tgz, 13MB)]({{ site.production_url }}/files/scalajs_2.11-0.5.1.tgz) +* [0.5.1, Scala 2.11 (zip, 13MB)]({{ site.production_url }}/files/scalajs_2.11-0.5.1.zip) +* [0.5.1, Scala 2.10 (tgz, 15MB)]({{ site.production_url }}/files/scalajs_2.10-0.5.1.tgz) +* [0.5.1, Scala 2.10 (zip, 15MB)]({{ site.production_url }}/files/scalajs_2.10-0.5.1.zip) #### Scala.js 0.5.0 -* [0.5.0, Scala 2.11 (tgz, 13MB)]({{ BASE_PATH }}/files/scalajs_2.11-0.5.0.tgz) -* [0.5.0, Scala 2.11 (zip, 13MB)]({{ BASE_PATH }}/files/scalajs_2.11-0.5.0.zip) -* [0.5.0, Scala 2.10 (tgz, 15MB)]({{ BASE_PATH }}/files/scalajs_2.10-0.5.0.tgz) -* [0.5.0, Scala 2.10 (zip, 15MB)]({{ BASE_PATH }}/files/scalajs_2.10-0.5.0.zip) +* [0.5.0, Scala 2.11 (tgz, 13MB)]({{ site.production_url }}/files/scalajs_2.11-0.5.0.tgz) +* [0.5.0, Scala 2.11 (zip, 13MB)]({{ site.production_url }}/files/scalajs_2.11-0.5.0.zip) +* [0.5.0, Scala 2.10 (tgz, 15MB)]({{ site.production_url }}/files/scalajs_2.10-0.5.0.tgz) +* [0.5.0, Scala 2.10 (zip, 15MB)]({{ site.production_url }}/files/scalajs_2.10-0.5.0.zip) diff --git a/index.md b/index.md index 583ab7b2..148ffa66 100644 --- a/index.md +++ b/index.md @@ -1,7 +1,7 @@ --- layout: page title: Scala.js -tagline: A Scala to JavaScript compiler +tagline: the Scala to JavaScript compiler --- {% include JB/setup %} @@ -22,10 +22,8 @@ and follow the instructions in its readme or [try it out in the browser](http:// We also have a [standalone distribution](./downloads.html) that doesn't require SBT. -
Important notice! Scala.js is still experimental! -Although this is a project of LAMP/EPFL for which we will continue to provide -best-effort improvements and bug fixes, it is not supported by Typesafe, -and not part of any of their support contracts. You have been warned!
+_Note that Scala.js is not part of the Typesafe Reactive platform. +Thus, although we consider Scala.js production-ready, Typesafe does not provide any commercial support for it._ ## Noteworthy features @@ -44,6 +42,8 @@ and not part of any of their support contracts. You have been warned! your browser supporting source maps) * Integrates [Google Closure Compiler](https://developers.google.com/closure/compiler/) for producing minimal code for production. Compiled blobs range from 170-400kb +* Produces (very) efficient JavaScript code + ([benchmarks](https://github.com/sjrd/scalajs-benchmarks)) ## Resources @@ -52,15 +52,10 @@ and not part of any of their support contracts. You have been warned! * [Official mailing list](https://groups.google.com/forum/?fromgroups#!forum/scala-js): for general discussion, ideas, announcements of your libraries, etc. * [Gitter chat room](https://gitter.im/scala-js/scala-js): come and meet the community of Scala.js users. -Presentations: +Featured presentations to get you convinced: -* [Hands-on Scala.js](http://vimeo.com/111978847) at PNWScala, by Li Haoyi -* [Cross-Platform Development in Scala.js](https://www.youtube.com/watch?v=Ksoi6AG9nbA), by Li Haoyi -* [Scala's evolving ecosystem- Introduction to Scala.js](http://blog.knoldus.com/2014/09/03/meet-up-on-scalas-evolving-ecosystem-introduction-to-scala-js/), by [Ayush Mishra](https://www.linkedin.com/pub/ayush-mishra/23/87b/a27), [Knoldus Software LLP](http://www.knoldus.com/home.knol) -* [Scala.js at Scaladays 2014](http://www.parleys.com/play/53a7d2cbe4b0543940d9e555), by Sébastien Doeraene -* [Live Coding Scala.js at SF Scala 2014](http://vimeo.com/87845442) by Li Haoyi -* [Live-coding with Scala.js at Scala eXchange 2013](http://skillsmatter.com/podcast/scala/scala-js-write-in-scala-for-the-browser-4567) -* [Presentation of Scala.js at Scala Days 2013](http://www.parleys.com/play/51c380bfe4b0ed8770356866) (older and somewhat obsolete) +* [Hands-on Scala.js](http://vimeo.com/111978847) at Pacific North-West Scala 2014, by Li Haoyi +* [Cross-Platform Development in Scala.js](https://www.youtube.com/watch?v=Ksoi6AG9nbA) at Scala by the Bay 2014, by Li Haoyi ## Libraries @@ -134,16 +129,12 @@ All these testing frameworks cross-compile on the JVM and JS. ## Miscellaneous -* [Port of the Dart benchmark harness](https://github.com/jonas/scala-js-benchmarks) - by Jonas Fonseca +* [Port of the Dart benchmark harness](https://github.com/sjrd/scalajs-benchmarks) ## Contribute * [Scala.js on GitHub](https://github.com/scala-js/scala-js) -Want to contribute to Scala.js? Check out the -[list of contributing opportunities](./contribute/). - ## Built with Scala.js List of websites using Scala.js: @@ -183,6 +174,7 @@ List of websites using Scala.js: ## Version History +- [0.6.0](/news/2015/02/05/announcing-scalajs-0.6.0/) - [0.6.0-RC2](/news/2015/01/23/announcing-scalajs-0.6.0-RC2/) - [0.6.0-RC1](/news/2015/01/12/announcing-scalajs-0.6.0-RC1/) - [0.6.0-M3](/news/2014/12/22/announcing-scalajs-0.6.0-M3/)