Skip to content

Commit 7598d13

Browse files
committed
Update scala-vs-vite-mill.md to be Mill specific
1 parent 399886c commit 7598d13

File tree

1 file changed

+45
-55
lines changed

1 file changed

+45
-55
lines changed

doc/tutorial/scalajs-vite-mill.md

Lines changed: 45 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
layout: doc
3-
title: Getting Started with Scala.js and Vite
3+
title: Getting Started with Scala.js and Vite using Mill
44
---
55

66
In this first tutorial, we learn how to get started with Scala.js and [Vite](https://vitejs.dev/).
@@ -96,59 +96,46 @@ Observe that the page automatically and instantaneously refreshes to show the ch
9696

9797
## Introducing Scala.js
9898

99-
We use [sbt](https://www.scala-sbt.org/) as a build tool for Scala and Scala.js.
99+
In this tutorial we will use [Mill](https://mill-build.org) as a build tool for Scala and Scala.js.
100100
We set it up as follows.
101101

102-
In the subdirectory `livechart/project/`, we add two files: `build.properties` and `plugins.sbt`.
102+
At the root of our `livechart/` project, we add one file: `build.mill`.
103103

104-
* `project/build.properties`: set the version of sbt
104+
* `build.mill`: the main Mill build
105105

106-
{% highlight plaintext %}
107-
sbt.version=1.10.0
108-
{% endhighlight %}
106+
{% highlight scala %}
107+
//| mill-version: 1.1.0-RC2
108+
//| mill-jvm-version: temurin:17.0.6
109109

110-
* `project/plugins.sbt`: declare sbt plugins; in this case, only sbt-scalajs
110+
package build
111111

112-
{% highlight scala %}
113-
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "{{ site.versions.scalaJS }}")
114-
{% endhighlight %}
112+
import mill.*, scalalib.*, scalajslib.*, scalajslib.api.*
115113

116-
At the root of our `livechart/` project, we add one file: `build.sbt`.
114+
trait AppScalaModule extends ScalaModule {
115+
def scalaVersion = "3.7.4"
116+
}
117117

118-
* `build.sbt`: the main sbt build
118+
trait AppScalaJSModule extends AppScalaModule, ScalaJSModule {
119+
def scalaJSVersion = "1.20.1"
120+
121+
def moduleKind = ModuleKind.ESModule
119122

120-
{% highlight scala %}
121-
import org.scalajs.linker.interface.ModuleSplitStyle
122-
123-
lazy val livechart = project.in(file("."))
124-
.enablePlugins(ScalaJSPlugin) // Enable the Scala.js plugin in this project
125-
.settings(
126-
scalaVersion := "3.3.3",
127-
128-
// Tell Scala.js that this is an application with a main method
129-
scalaJSUseMainModuleInitializer := true,
130-
131-
/* Configure Scala.js to emit modules in the optimal way to
132-
* connect to Vite's incremental reload.
133-
* - emit ECMAScript modules
134-
* - emit as many small modules as possible for classes in the "livechart" package
135-
* - emit as few (large) modules as possible for all other classes
136-
* (in particular, for the standard library)
137-
*/
138-
scalaJSLinkerConfig ~= {
139-
_.withModuleKind(ModuleKind.ESModule)
140-
.withModuleSplitStyle(
141-
ModuleSplitStyle.SmallModulesFor(List("livechart")))
142-
},
143-
144-
/* Depend on the scalajs-dom library.
145-
* It provides static types for the browser DOM APIs.
146-
*/
147-
libraryDependencies += "org.scala-js" %%% "scalajs-dom" % "{{ site.versions.scalaJSDOM }}",
148-
)
123+
def scalaJSSourceMap = false
124+
}
125+
126+
object `package` extends AppScalaModule {
127+
128+
object livechart extends AppScalaJSModule {
129+
def moduleSplitStyle = ModuleSplitStyle.SmallModulesFor("livechart")
130+
131+
def mvnDeps = Seq(
132+
mvn"org.scala-js::scalajs-dom::2.8.1",
133+
)
134+
}
135+
}
149136
{% endhighlight %}
150137

151-
Finally, we write the following content in the file `src/main/scala/livechart/LiveChart.scala`:
138+
Mill will expect to find a subdirectory called livechart at `livechart/livechart` because that is what we named the `AppScalaJsModule` in our `build.mill`. And finally, we write the following content in the file `livechart/livechart/src/LiveChart.scala`:
152139

153140
{% highlight scala %}
154141
package livechart
@@ -233,33 +220,35 @@ Since it represents a file path, we declare `javascriptLogo` as a `String`.
233220
The `= js.native` is a Scala.js idiosyncrasy: we need a concrete value to satisfy the Scala typechecker.
234221
In an ideal world, it would not be required.
235222

236-
We can now build the Scala.js project by opening a new console, and entering sbt:
223+
We can now build the Scala.js project by opening a new console, and running the following Mill command:
237224

238225
{% highlight shell %}
239-
$ sbt
226+
$ mill -w livechart.fastLinkJS
240227
[...]
241-
sbt:livechart> ~fastLinkJS
228+
Watching for changes to 12 paths and 11 other values... (Enter to re-run, Ctrl-C to exit)
242229
{% endhighlight %}
243230

244231
The `fastLinkJS` task produces the `.js` outputs from the Scala.js command.
245-
The `~` prefix instructs sbt to re-run that task every time a source file changes.
232+
The `-w` command line parameter instructs Mill to re-run that task every time a source file changes.
246233

247234
There is one thing left to change: replace the hand-written JavaScript code with our Scala.js application.
248-
We use the `@scala-js/vite-plugin-scalajs` plugin to link Vite and Scala.js with minimal configuration.
235+
We use the `vite-plugin-scalajs-mill` plugin to link Vite and Scala.js with minimal configuration.
249236
We install it in the dev-dependencies with:
250237

251238
{% highlight shell %}
252-
$ npm install -D @scala-js/vite-plugin-scalajs@1.0.0
239+
$ npm install -D vite-plugin-scalajs-mill@1.0.1
253240
{% endhighlight %}
254241

255242
and instruct Vite to use it with the following configuration in a new file `vite.config.js`:
256243

257244
{% highlight javascript %}
258245
import { defineConfig } from "vite";
259-
import scalaJSPlugin from "@scala-js/vite-plugin-scalajs";
246+
import scalaJSMillPlugin from "vite-plugin-scalajs-mill";
260247

261248
export default defineConfig({
262-
plugins: [scalaJSPlugin()],
249+
plugins: [scalaJSMillPlugin({
250+
moduleNames: "livechart"
251+
})],
263252
});
264253
{% endhighlight %}
265254

@@ -270,7 +259,7 @@ import './style.css'
270259
import 'scalajs:main.js'
271260
{% endhighlight %}
272261

273-
When we `import` a URI starting with `scalajs:`, `vite-plugin-scalajs` resolves it to point to the output directory of Scala.js' `fastLinkJS` task.
262+
When we `import` a URI starting with `scalajs:`, `vite-plugin-scalajs-mill` resolves it to point to the output directory of Scala.js' `fastLinkJS` task.
274263

275264
You may have to stop and restart the `npm run dev` process, so that Vite picks up the newly created configuration file.
276265
Vite will refresh the browser with our updated "Hello Scala.js!" message.
@@ -298,7 +287,7 @@ Once we save, we notice that the browser refreshes with the updated message.
298287

299288
There are two things happening behind the scenes:
300289

301-
1. The `~fastLinkJS` task in sbt notices that a `.scala` file has changed, and therefore rebuilds the `.js` output.
290+
1. The `~fastLinkJS` task in Mill notices that a `.scala` file has changed, and therefore rebuilds the `.js` output.
302291
1. The `npm run dev` process with Vite notices that a `.js` file imported from `/main.js` has changed, and triggers a refresh with the updated files.
303292

304293
All these steps are *incremental*.
@@ -309,11 +298,12 @@ This ensures that the development cycle remains as short as possible.
309298

310299
## Production build
311300

312-
The `fastLinkJS` task of sbt and the `npm run dev` task of Vite are optimized for incremental development.
301+
The `fastLinkJS` task of Mill and the `npm run dev` task of Vite are optimized for incremental development.
313302
For production, we want to perform more optimizations on the Scala.js side and bundle minimized files with `npm run build`.
314303
We stop Vite with `Ctrl+C` and launch the following instead:
315304

316305
{% highlight shell %}
306+
$ mill livechart.fullLinkJS
317307
$ npm run build
318308

319309
> livechart@0.0.0 build
@@ -348,7 +338,7 @@ Navigate to the mentioned URL to see your website.
348338

349339
## Conclusion
350340

351-
In this tutorial, we saw how to configure Scala.js with Vite from the ground up using `@scala-js/vite-plugin-scalajs`.
341+
In this tutorial, we saw how to configure Scala.js with Vite from the ground up using `vite-plugin-scalajs-mill`.
352342
We used sbt as our build tool, but the same effect can be achieved with any other Scala build tool, such as [Mill](https://com-lihaoyi.github.io/mill/) or [scala-cli](https://scala-cli.virtuslab.org/).
353343

354344
Our setup features the following properties:

0 commit comments

Comments
 (0)