Skip to content

Commit 1748597

Browse files
committed
Update documentation for 1.3.x
As a side effect, update the Node.js ES module support section.
1 parent b408f27 commit 1748597

File tree

5 files changed

+61
-41
lines changed

5 files changed

+61
-41
lines changed

doc/project/building.md

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,12 @@ This will generate `.sjsir` and `.class` files for each class in your project (j
1111

1212
The `.sjsir` files are an internal representation which can be linked to actual JavaScript code as will be explained shortly.
1313

14-
## Produce one JavaScript file
15-
16-
To produce a proper JavaScript file from your code, you need to call the linker:
17-
18-
sbt> fastOptJS
19-
20-
This will perform fast Scala.js-specific optimizations and write the resulting code to a single JavaScript file. You can now use this JavaScript file in your HTML page or in whatever way you like. The resulting file in the target folder will have the suffix `-fastopt.js`.
21-
2214
## Actually *do* something
2315

24-
By default, Scala.js produces "libraries", that do not actually *do* anything when their `-fastopt.js` file is loaded.
25-
To make it do something, you need a top-level object with a `main` method:
16+
To produce JavaScript code, we need to either export something (e.g. a method or a class) or do something when the JavaScript code is loaded.
17+
Otherwise, Scala.js will not produce any JavaScript code (because to do nothing, there is no need for any code).
18+
19+
To do something when your code is loaded, you need a top-level object with a `main` method (to export something, see [Export Scala.js APIs to JavaScript]({{ site.production_url }}/doc/interoperability/export-to-javascript.html)).
2620

2721
{% highlight scala %}
2822
object Main {
@@ -39,7 +33,6 @@ scalaJSUseMainModuleInitializer := true
3933
{% endhighlight %}
4034

4135
Just like in a JVM project, sbt will automatically detect the object with a `main(Array[String]): Unit` method, and use it as the main method of the application.
42-
Now, the .js file produced by `fastOptJS` will print `"Hello world!"`.
4336

4437
Note that this will require that there is a *unique* such object or that the one to use be explicitly set with `mainClass in Compile := Some(<name>)`.
4538
If you explicitly set `mainClass`, note that it needs to be set on a per-configuration basis (i.e. the part `in Compile` is essential, otherwise the setting will be ignored). For further information see the Stack Overflow entry ['How to set mainClass in ScalaJS build.sbt?'](http://stackoverflow.com/questions/34965072/how-to-set-mainclass-in-scalajs-build-sbt) (specific to Scala.js) and the Stack Overflow entry ['How to set main class in build?'](http://stackoverflow.com/questions/6467423/how-to-set-main-class-in-build) (not specific to Scala.js).
@@ -49,14 +42,29 @@ Since 0.6.18, any object with a standard `main` method will be recognized.
4942
`js.JSApp` is now deprecated.
5043
See [the Scaladoc of `js.JSApp`]({{ site.production_url }}/api/scalajs-library/0.6.20/#scala.scalajs.js.JSApp) for migration tips.
5144

45+
## Produce JavaScript code
46+
47+
To produce JavaScript code from your Scala code, you need to call the linker:
48+
49+
sbt> fastLinkJS
50+
51+
This will perform fast Scala.js-specific optimizations and write the resulting JavaScript code to a directory.
52+
With the default options, it will write a single file `main.js`.
53+
You can now use this JavaScript file in your HTML page or in whatever way you like.
54+
The resulting directory in the target folder will have the suffix `-fastopt`.
55+
56+
Loading the `main.js` file produced by `fastLinkJS` will print `"Hello world!"`.
57+
58+
**Note for Scala.js 1.2.x and earlier:** in Scala.js 1.2.x and earlier, we used `fastOptJS` instead of `fastLinkJS`, which always produces a single file with the suffix `-fastopt.js` directly in the target directory.
59+
5260
## Running in the console
5361

5462
You can run a Scala.js application (that has `scalaJSUseMainModuleInitializer` set to `true`) by using the `run` task:
5563

5664
sbt> run
5765

58-
This will run the `-fastopt.js` file right inside of your sbt console.
59-
By default, the file is run with [Node.js](http://nodejs.org/), which you need to install separately.
66+
This will run the `main.js` file right inside of your sbt console.
67+
By default, the file is run with [Node.js](https://nodejs.org/), which you need to install separately.
6068

6169
**Scala.js 0.6.x only:** If your application or one of its libraries requires a DOM (which can be specified with `jsDependencies += RuntimeDOM`), you will also need to install [`jsdom`](https://github.com/jsdom/jsdom) with `npm install jsdom`.
6270
`jsDependencies += RuntimeDOM` is now deprecated, and should be replaced by `jsEnv := new org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv()`.
@@ -86,16 +94,19 @@ See [the Scaladoc of `StandardLinker.Config`]({{ site.production_url }}/api/scal
8694

8795
To make the resulting JavaScript even smaller (and usually faster as well), the sbt plugin integrates the Google Closure Compiler under the so-called full-optimizations. You can use them by issuing:
8896

89-
sbt> fullOptJS
97+
sbt> fullLinkJS
9098

91-
This will produce another single JavaScript file that is fully optimized.
99+
This will produce a `main.js` file that is fully optimized in another directory.
92100
Note that this can take a while and is therefore not recommended in the development cycle.
93-
The resulting file in the target folder will have the suffix `-opt.js`.
101+
The resulting directory in the target folder will have the suffix `-opt`.
94102

95103
You can run your code and tests in fullOpt stage with the following command:
96104

97105
sbt> set scalaJSStage in Global := FullOptStage
98106

107+
**Note for Scala.js 1.2.x and earlier:** in Scala.js 1.2.x and earlier, we used `fullOptJS` instead of `fullLinkJS`, which always produces a single file with the suffix `-opt.js`.
108+
`scalaJSStage` works the same way in Scala.js 1.2.x and in later versions.
109+
99110
## Deprecated: Writing Launcher Code
100111

101112
**Scala.js 0.6.x only**

doc/project/linking-errors.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@ layout: doc
33
title: Linking Errors
44
---
55

6-
When linking a Scala.js application, either directly through `fastOptJS`/`fullOptJS` or indirectly through `run` or `test`, Scala.js can sometimes report *linking errors*.
6+
When linking a Scala.js application, either directly through `fastLinkJS`/`fullLinkJS` (`fastOptJS`/`fullOptJS` up to Scala.js 1.2.x) or indirectly through `run` or `test`, Scala.js can sometimes report *linking errors*.
77
They look like the following:
88

99
```
10-
[info] Fast optimizing .../helloworld/target/scala-2.12/helloworld-fastopt.js
10+
[info] Fast optimizing .../helloworld/target/scala-2.12/helloworld-fastopt
1111
[error] Referring to non-existent method scala.concurrent.impl.Promise$CompletionLatch.releaseShared(scala.Int)scala.Boolean
1212
[error] called from scala.concurrent.impl.Promise$CompletionLatch.apply(scala.util.Try)scala.Unit
1313
[error] called from scala.concurrent.impl.Promise$CompletionLatch.apply(java.lang.Object)java.lang.Object
1414
[error] ...
1515
[error] There were linking errors
16-
[error] (helloworld/compile:fastOptJS) There were linking errors
16+
[error] (helloworld/compile:fastLinkJS) There were linking errors
1717
[error] Total time: 2 s, completed Sep 13, 2019 1:30:39 PM
1818
```
1919

@@ -97,7 +97,7 @@ libraryDependencies += "io.suzaku" %%% "boopickle" % "1.3.1"
9797
```
9898

9999
```
100-
[info] Fast optimizing .../helloworld/target/scala-2.12/helloworld-fastopt.js
100+
[info] Fast optimizing .../helloworld/target/scala-2.12/helloworld-fastopt
101101
[success] Total time: 3 s, completed Sep 13, 2019 1:44:25 PM
102102
```
103103

doc/project/module.md

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -82,26 +82,35 @@ exports.Babar = Foobaz;
8282

8383
## ES modules and Node.js
8484

85-
Support for ECMAScript modules is [still experimental in Node.js](https://nodejs.org/api/esm.html).
86-
To run and test a Scala.js application or library using ES modules with Node.js, you will need the following additional settings:
85+
Node.js needs explicit signaling that a module is an ECMAScript module (the default is CommonJS).
86+
87+
There are two ways to achieve this:
88+
* Use the file extension `.mjs`.
89+
* Configure it in `package.json`.
90+
91+
For details, see the [Node.js packages documentation](https://nodejs.org/api/packages.html#packages_determining_module_system).
92+
93+
To set the extension used by Scala.js to `.mjs` use the following setting:
8794

8895
{% highlight scala %}
89-
jsEnv := {
90-
new org.scalajs.jsenv.NodeJSEnv(
91-
org.scalajs.jsenv.NODEJSEnv.Config()
92-
.withArguments(List("--experimental-modules"))
93-
)
96+
import org.scalajs.linker.interface.OutputPatterns
97+
98+
scalaJSLinkerConfig ~= {
99+
// Enable ECMAScript module output.
100+
_.withModuleKind(ModuleKind.ESModule)
101+
// Use .mjs extension.
102+
.withOutputPatterns(OutputPatterns.fromJSFile(".mjs"))
94103
}
104+
{% endhighlight %}
95105

106+
**Note for Scala.js 1.2.x and earlier:**
107+
108+
`OutputPatterns` was introduced in Scala.js 1.3.0. In earlier versions, the following settings were necessary:
109+
110+
{% highlight scala %}
96111
artifactPath in (proj, Compile, fastOptJS) :=
97112
(crossTarget in (proj, Compile)).value / "myproject.mjs"
98113

99114
artifactPath in (proj, Test, fastOptJS) :=
100115
(crossTarget in (proj, Test)).value / "myproject-test.mjs"
101116
{% endhighlight %}
102-
103-
The first setting is required to enable the support of ES modules in Node.js.
104-
The other two make sure that the JavaScript produced have the extension `.mjs`, which is required for Node.js to interpret them as ES modules.
105-
106-
The support for running and testing ES modules with Node.js is *experimental*, as the support of ES modules by Node.js is itself experimental.
107-
Things could change in future versions of Node.js and/or Scala.js.

doc/project/testing.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,9 @@ A list of testing frameworks compatible with Scala.js can be found [here](../../
7575

7676
Note: Don't forget to mark a test framework SBT dependency as `test,it` if you have both unit and integration tests.
7777

78-
## Testing over `fullOptJS`-generated files
78+
## Testing over `fullLinkJS`-generated files
7979

80-
By default, tests runs over `fastOptJS`-built JS files since their build time are shorter than `fullOptJS`.
80+
By default, tests run over `fastLinkJS`-built (resp. `fastOptJS` up to Scala.js 1.2.x) JS files since their build time is shorter than `fullLinkJS` (resp. `fullLinkJS`).
8181

82-
If you want to run tests over `fullOptJS`-build JS files for some reason, run `set scalaJSStage in Global := FullOptStage` before test.
82+
If you want to run tests over `fullLinkJS`-build JS files for some reason, run `set scalaJSStage in Global := FullOptStage` before test.
8383
This increases test time significantly, and omit checks for undefined behavior, so not recommended in default build settings. Instead, consider run test both in `FastOptStage` and `FullOptStage` in CI.

doc/semantics.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,20 +127,20 @@ Every configurable undefined behavior has 3 possible modes:
127127
* `Unchecked`: completely unchecked and undefined
128128
* `Fatal`: checked, but throws `UndefinedBehaviorError`s instead of the specified exception
129129

130-
By default, undefined behaviors are in `Fatal` mode for `fastOptJS` and in
131-
`Unchecked` mode for `fullOptJS`.
130+
By default, undefined behaviors are in `Fatal` mode for `fastLinkJS` and in
131+
`Unchecked` mode for `fullLinkJS` (`fastOptJS` / `fullOptJS` up to Scala.js 1.2.x).
132132
This is so that bugs can be detected more easily during development, with
133133
predictable exceptions and stack traces.
134-
In production code (`fullOptJS`), the checks are removed for maximum
134+
In production code (`fullLinkJS`), the checks are removed for maximum
135135
efficiency.
136136

137137
`UndefinedBehaviorError`s are *fatal* in the sense that they are not matched by
138138
`case NonFatal(e)` handlers.
139139
This makes sure that they always crash your program as early as possible, so
140140
that you can detect and fix the bug.
141141
It is *never* OK to catch an `UndefinedBehaviorError` (other than in a testing
142-
framework), since that means your program will behave differently in `fullOpt`
143-
stage than in `fastOpt`.
142+
framework), since that means your program will behave differently in `fullLinkJS`
143+
stage than in `fastLinkJS`.
144144

145145
If you need a particular kind of exception to be thrown in compliance with the
146146
JVM semantics, you can do so with an sbt setting.

0 commit comments

Comments
 (0)