docs(book): Add Part VIII — Scala.js and the NPM ecosystem (facades + Vite)#595
Conversation
Two new chapters on using JavaScript libraries from a Scala.js Uni app, without ScalablyTyped: - ch12 Calling NPM Modules — hand-written facades with @js.native + @jsimport (default vs named exports), js.* types, the js.Dynamic escape hatch, and why a few honest lines beat a generated TS-to-Scala library. - ch13 Bundling with Vite — ModuleKind.ESModule so @jsimport emits real imports; npm install; a main.js entry that loads the Scala.js output; the @jsglobal+window bridge and resolve.alias escape hatch for stubborn modules. Patterns are grounded in the wvlet-ui-playground reference (vite.config, main.js window-bridge, koffi alias stub) and the verified Koffi.scala facade; ESModule linker config confirmed against uni's own build. Wires Part VIII into the ToC and /book/ sidebar, and re-threads the nav (ch11 → 12 → 13 → appendices). pnpm docs:build passes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request introduces Part VIII to the documentation, adding Chapter 12 on writing hand-written Scala.js facades for npm modules and Chapter 13 on bundling Scala.js ES modules with Vite. Feedback on the new chapters suggests declaring methods in @js.native traits as abstract without = js.native to prevent compilation errors, and correcting the sbt output paths from scala-3.x to scala-3 to match standard Scala 3 builds.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
|
|
||
| @js.native | ||
| trait Connection extends js.Object: | ||
| def query(sql: String): js.Array[js.Any] = js.native |
There was a problem hiding this comment.
In Scala.js, members of a @js.native trait must be abstract. Defining a method with = js.native inside a native trait is redundant and can cause compilation errors in some Scala.js versions. It should be declared without a body.
| def query(sql: String): js.Array[js.Any] = js.native | |
| def query(sql: String): js.Array[js.Any] |
| to see. (Uni's own JS builds use exactly this setting.) | ||
|
|
||
| `sbt app/fastLinkJS` then produces a folder of ES modules under | ||
| `target/scala-3.x/app-fastopt/`, with `main.js` as the entry. The |
| import './style.css' | ||
|
|
||
| // Start the Scala.js application (the fastLinkJS output entry module) | ||
| import('./target/scala-3.x/app-fastopt/main.js') |
Adds a new Part VIII to The Uni Book on using the JavaScript/npm ecosystem from a Scala.js Uni app — without ScalablyTyped, as requested.
Chapters
@js.native+@JSImport(default vs named exports), thejs.*type vocabulary, thejs.Dynamicescape hatch, and a clear-eyed why not ScalablyTyped (a few honest lines beat a generated TS→Scala library for the handful of calls a real app makes).ModuleKind.ESModuleso@JSImportemits real imports;npm install; amain.jsentry that loads the Scala.js output and lets Vite resolve the bare imports; and the two real-world escape hatches — the@JSGlobal+windowbridge andresolve.aliasfor browser-hostile transitive deps.Grounded in real code
Patterns come from the
wvlet-ui-playgroundreference you pointed to:Koffi.scalafacade (@JSImport("koffi", JSImport.Default)),vite.config.js(resolve.aliaskoffi→stub,base: "./"),main.js(window.MonacoEditorbridge, dynamic import of the Scala.js output), andpackage.json,ModuleKind.ESModuleconfirmed against both uni's and wvlet'sbuild.sbt.Wiring
/book/sidebar.prevupdated accordingly).pnpm docs:buildpasses (dead-link-clean).🤖 Generated with Claude Code