Skip to content

Commit 72b314b

Browse files
committed
Merge pull request #54 from gzm0/various-fixes
Various fixes
2 parents 8e807fd + 261f057 commit 72b314b

File tree

3 files changed

+70
-67
lines changed

3 files changed

+70
-67
lines changed

doc/faq.md

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,11 @@ title: Frequently Asked Questions
66

77
### How to structure a .sbt build to cross-compile with Scala and Scala.js?
88

9-
The best way to do this is two have two sbt projects, with two different base
10-
directories, that share their source directory. This is easily done with the
11-
`sourceDirectory` setting of sbt.
9+
The best way to do this is to have two sbt projects, with two different base
10+
directories that share a common source directory. This is easily done with the
11+
`sourceDirectory` or the `unmanagedSourceDirectories` setting of sbt.
1212

13-
{% highlight scala %}
14-
lazy val core = project
15-
16-
lazy val corejs = project.settings(
17-
scalaJSSettings:_*
18-
).settings(
19-
sourceDirectory := (sourceDirectory in core).value
20-
)
21-
{% endhighlight %}
13+
Please follow our [cross-building guide](./sbt/cross-building.html) for details.
2214

2315
### Can I use macros with Scala.js? What about compiler plugins?
2416

@@ -36,3 +28,19 @@ asm.js was designed as a target for C-like languages, that consider the memory
3628
as a huge array of bytes, and with manual memory management. By their own
3729
acknowledgment (see [their FAQ](http://asmjs.org/faq.html)), it is not a good
3830
target for managed languages like Scala.
31+
32+
### My `jsDependencies` do not work / are not included when running / testing in `fastOptStage` and `fullOptStage`
33+
34+
Some JavaScript libraries alter their behavior when included, depending on the including environment (Browser, CommonJS, RequireJS, Node.js, etc.). Since the inclusion semantics of the Scala.js sbt plugin corresponds to a `<script>` tag in an HTML page, this behavior may make the inclusion fail on [Node.js](http://nodejs.org/) (which is the default JavaScript VM for `fastOptStage` and `fullOptStage`).
35+
36+
We currently do not know how to fix this behavior, so the "official fix" is to use [PhantomJS](http://phantomjs.org/) instead by setting
37+
38+
postLinkJSEnv := new scala.scalajs.sbtplugin.env.phantomjs.PhantomJSEnv
39+
40+
in the concerned build files (of course you will also need to [install PhantomJS](http://phantomjs.org/download.html)).
41+
42+
JavaScript libraries which are known to be affected by this are:
43+
44+
- [`mustache.js`](https://github.com/janl/mustache.js)
45+
46+
We keep track of this issue in [#706](https://github.com/scala-js/scala-js/issues/706). You are encouraged to comment and contribute if you know something more about this or if the JavaScript library you use is affected by this.

doc/internals/compile-opt-pipeline.md

Lines changed: 49 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,21 @@ title: Compilation and optimization pipeline
77
From Scala source files to optimized JavaScript code, there are a few steps
88
which are described in this document.
99

10-
* *compiling*: compile .scala files to 1 .js file per class using the scalac
10+
* *compiling*: compile .scala files to 1 .sjsir file per class using the scalac
1111
compiler with the Scala.js compiler plugin.
1212

13-
For libraries, it stops here. The compiled .js files, their source maps and
14-
the .sjsinfo files are put together with .class files in the binary jars that
13+
For libraries, it stops here. The compiled .sjsir files are put together with .class files in the binary jars that
1514
can be published to an Ivy or Maven repository.
1615

1716
For the application project, one more mandatory step creates 1 or 3 .js files
1817
consumable by browsers. Then an optional step can be used to optimize the
1918
result.
2019

21-
* *linking* all the .js files together, including those in transitive
20+
* *linking* all the .sjsir files together, including those in transitive
2221
dependencies. This is either one of:
23-
* *packaging*: concatenate blindly all compiled .js files in 3 big .js files.
24-
* *preoptimizing*: apply a type-aware inter-method global dead code
22+
* *fastoptimizing*: apply a type-aware inter-method global dead code
2523
elimination that results in 1 preoptimized .js file.
24+
* *packaging*: concatenate blindly all compiled .sjsir files in 3 big .js files. This used to be the default in earlier versions of Scala.js. Packaging is discouraged and might fall away in future versions since the fast optimization is now faster.
2625
* *optimizing* (optional, with the
2726
[Closure Compiler](https://developers.google.com/closure/compiler/)): apply
2827
the Closure Compiler to the linked .js file(s).
@@ -33,29 +32,51 @@ Compilation is similar to using the Scala compiler daily. .scala source files
3332
are compiled with incremental compilation by the Scala compiler. They can
3433
depend on external libraries or other projects in the build, as usual.
3534

36-
The Scala.js compiler plugin produces .js files in addition to the .class files
37-
generated by scalac. Roughly one .js file is produced for each .class file.
38-
(Sometimes, fewer .js files are necessary when the compiler can optimize
35+
The Scala.js compiler plugin produces .sjsir files in addition to the .class files
36+
generated by scalac. Roughly one .sjsir file is produced for each .class file.
37+
(Sometimes, fewer .sjsir files are necessary when the compiler can optimize
3938
anonymous function classes as JavaScript functions.)
4039

41-
For each class, three files are emitted:
40+
An .sjsir file contains a Scala.js specific intermediate representation. You may use `scalajsp` from the Scala.js [CLI]({{ BASE_PATH }}/downloads.html) to display it in a human readable form.
4241

43-
* `TheClass.js`: the JavaScript code for the class, its methods, its runtime
44-
class data, and, for module classes, the module accessor.
45-
* `TheClass.js.map`: the source map linked to `TheClass.js`.
46-
* `TheClass.sjsinfo`: additional information used by the linkers (packaging or
47-
preoptimizing).
48-
49-
These files are bundled together with .class files in jars published on Ivy or
42+
The .sjsir files are bundled together with .class files in jars published on Ivy or
5043
Maven repositories.
5144

5245
This step completely supports separate compilation and incremental compilation,
5346
just like the regular Scala compiler.
5447

48+
## Fast Optimzing
49+
50+
The size of the JavaScript files produced by blindly concatenating .sjsir files are huge.
51+
They are always bigger than 20 MB because they include the full Scala standard
52+
library.
53+
But typically, only a small fraction of the libraries you depend on are
54+
actually used.
55+
56+
Fast optimizing is a task that identifies all the classes and methods reachable
57+
from a given set of entry points, and removes everything else.
58+
Entry points are classes and methods that are
59+
[exported to JavaScript]({{ BASE_PATH }}/doc/export-to-javascript.html).
60+
61+
The fast optimizer uses information stored by the compilation step in .sjsir
62+
to derive a reachability graph from the entry points.
63+
Then it produces a single .js file containing all the code that is actually
64+
useful (or, since in theory the algorithm computes an over-approximation, all
65+
the code that could not be proved to be useless).
66+
67+
In sbt, the fast optimizing task is called `fastOptJS`. The result of
68+
fast optimization is typically between 1.5 MB and 2.5 MB.
69+
70+
The fast optimizer can also be called programmatically using the class
71+
[ScalaJSOptimizer](https://github.com/scala-js/scala-js/blob/master/tools/src/main/scala/scala/scalajs/tools/optimizer/ScalaJSOptimizer.scala)
72+
in the Scala.js toolbox.
73+
5574
## Packaging
5675

57-
Packaging is the simplest form of linking. Conceptually, it simply takes the
58-
.js files generated by the compilation step for all the transitive dependencies
76+
**Packaging is discouraged, since fast optimizing has become faster. This section is for information only, as packaging can be useful for very specific use-cases.**
77+
78+
Packaging is the simplest form of linking. Conceptually, it simply takes the JavaScript code in the
79+
.sjsir files generated by the compilation step for all the transitive dependencies
5980
of the project and concatenates them.
6081
There are however 2 subtleties: a decomposition in 3 files for performance,
6182
and an ordering for correctness.
@@ -75,13 +96,13 @@ code that changes on every single dev cycle are in the project itself, which
7596
are the *exported products* of the project.
7697

7798
The packaging takes advantage of this obversation by producing 3 .js files
78-
instead of just 1: `app-extdeps.js` contains the external dependencies,
79-
`app-intdeps.js` contains the internal dependencies, and `app.js` contains the
99+
instead of just 1: `app-pack-extdeps.js` contains the external dependencies,
100+
`app-pack-intdeps.js` contains the internal dependencies, and `app-pack-app.js` contains the
80101
exported products.
81-
`app-extdeps.js` is typically very large (the Scala standard library itself
102+
`app-pack-extdeps.js` is typically very large (the Scala standard library itself
82103
accounts for more than 20 MB of JavaScript code), but need not be repackaged
83104
often.
84-
`app.js` has to be repackaged on every single dev cycle, but contains
105+
`app-pack-app.js` has to be repackaged on every single dev cycle, but contains
85106
relatively much fewer code, and so this is fast.
86107

87108
### Ordering
@@ -90,48 +111,22 @@ The internal structure of the produced .js files imposes a constraint on the
90111
order in which they are packaged. A class must always be packaged after its
91112
superclass (and hence, transitively, all its superclasses).
92113

93-
To do so, the .sjsinfo file contains (among other things), the number of class
114+
To do so, the .sjsir file contains (among other things), the number of class
94115
ancestors of each class. Since a subclass *A* of a superclass *B* has at least
95116
one more ancestor than *B* (namely, *B*), it is sufficient, to guarantee the
96117
required ordering, that classes with more ancestors are ordered after classes
97118
with less ancestors.
98119

99-
## Preoptimizing
100-
101-
The size of the JavaScript files produced by packaging are huge.
102-
They are always bigger than 20 MB because they include the full Scala standard
103-
library.
104-
But typically, only a small fraction of the libraries you depend on are
105-
actually used.
106-
107-
Preoptimizing is a task that identifies all the classes and methods reachable
108-
from a given set of entry points, and removes everything else.
109-
Entry points are classes and methods that are
110-
[exported to JavaScript]({{ BASE_PATH }}/doc/export-to-javascript.html).
111-
112-
The preoptimizer uses information stored by the compilation step in .sjsinfo
113-
to derive a reachability graph from the entry points.
114-
Then it produces a single .js file containing all the code that is actually
115-
useful (or, since in theory the algorithm computes an over-approximation, all
116-
the code that could not be proved to be useless).
117-
118-
In sbt, the preoptimizing task is called `preoptimizeJS`. The result of
119-
preoptimization is typically between 1.5 MB and 2.5 MB.
120-
121-
The preoptimizer can also be called programmatically using the class
122-
[ScalaJSOptimizer](https://github.com/scala-js/scala-js/blob/master/tools/src/main/scala/scala/scalajs/tools/optimizer/ScalaJSOptimizer.scala)
123-
in the Scala.js toolbox.
124-
125120
## Optimizing using Closure
126121

127122
Scala.js emits code that is always guaranteed to follow the
128123
[restrictions](https://developers.google.com/closure/compiler/docs/limitations)
129124
imposed by the Advanced Optimizations of the Google Closure Compiler.
130-
Hence, we can optimize the linked JavaScript files (either packaged or
131-
preoptimized) using Closure.
125+
Hence, we can optimize the linked JavaScript files (either fast optimized or
126+
packaged) using Closure.
132127

133-
In sbt, the optimizing task is called `optimizeJS` and is applied on the result
134-
of `preoptimizeJS` by default. The result optimization is typically between
128+
In sbt, the optimizing task is called `fullOptJS` and is applied on the result
129+
of `fastOptJS`. The result optimization is typically between
135130
150 KB and a few hundreds of KB.
136131

137132
The optimizer can also be called programmatically using the class

index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ Presentations:
9696
Want to contribute to Scala.js? Check out the
9797
[list of contributing opportunities](./contribute/).
9898

99-
## Built with Scala.js
99+
## <a name="built_with_scalajs"></a> Built with Scala.js
100100

101101
Beginning a list of websites using Scala.js:
102102

0 commit comments

Comments
 (0)