-
-
Notifications
You must be signed in to change notification settings - Fork 360
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Seeks to address #3837 I have some outstanding questions; 1. As I'm altering the scalaJSModule public API, a double check here would be welcomed. In particular, I've just called the module property `emitWasm`. sjrd pretty clearly called the linker API `withExperimentalUseWebAssembly`. However, if at some point it became non-experimental, I assume that's a compatibility problem. Advice welcomed - I've gone with the simplest name possible - `emitWasm`. 2. CI will fail, because node is < 22. The runnable test does work locally for me. Does mill require, assume or otherwise advertise compatibility with any particular node version? If not, I'll simply push the node version forward in the GHA definitions. OItherwise, I'd welcome advice - I'm not clear what the best way to manage the CI would be. Those are the two points where I'd welcome advice. I think this is the path to victory; - [x] public API check? - [x] node version - [x] documentation - [x] CI green
- Loading branch information
Showing
10 changed files
with
200 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package build | ||
import mill._, scalalib._, scalajslib._ | ||
import mill.scalajslib.api._ | ||
|
||
|
||
object wasm extends ScalaJSModule { | ||
override def scalaVersion = "2.13.14" | ||
|
||
override def scalaJSVersion = "1.17.0" | ||
|
||
override def moduleKind = ModuleKind.ESModule | ||
|
||
override def moduleSplitStyle = ModuleSplitStyle.FewestModules | ||
|
||
override def scalaJSExperimentalUseWebAssembly = true | ||
} | ||
|
||
// This build defines a single `ScalaJSModule` that uses the `WASM` backend of the scala JS linker. | ||
// The release notes that introduced scalaJS wasm are here; | ||
// https://www.scala-js.org/news/2024/09/28/announcing-scalajs-1.17.0/ | ||
// and are worth reading. They include information such as the scala JS requirements to successfully emit wasm, | ||
// the flags needed to run in browser and the minimum node version (22) required to actually run the wasm output. | ||
|
||
/** Usage | ||
|
||
> ./mill show wasm.fastLinkJS # mac/linux | ||
{ | ||
... | ||
..."jsFileName": "main.js", | ||
... | ||
"dest": ".../out/wasm/fastLinkJS.dest" | ||
} | ||
|
||
> node --experimental-wasm-exnref out/wasm/fastLinkJS.dest/main.js # mac/linux | ||
hello wasm! | ||
|
||
*/ | ||
|
||
// Here we see that scala JS emits a single WASM module, as well as a loader and main.js file. | ||
// `main.js` is the entry point of the program, and calls into the wasm module. | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package wasm | ||
|
||
object wasm { | ||
def main(args: Array[String]): Unit = { | ||
println("hello wasm!") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package app | ||
|
||
import scala.scalajs.js | ||
import scala.scalajs.js.annotation._ | ||
|
||
object App { | ||
def main(args: Array[String]): Unit = { | ||
println("hello, wasm!") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package mill.scalajslib | ||
|
||
import mill.api.Result | ||
import mill.define.Discover | ||
import mill.testkit.UnitTester | ||
import mill.testkit.TestBaseModule | ||
import utest._ | ||
import mill.scalajslib.api._ | ||
import mill.T | ||
|
||
object WasmTests extends TestSuite { | ||
val remapTo = "https://cdn.jsdelivr.net/gh/stdlib-js/array-base-linspace@esm/index.mjs" | ||
|
||
object Wasm extends TestBaseModule with ScalaJSModule { | ||
override def scalaVersion = sys.props.getOrElse("TEST_SCALA_2_13_VERSION", ???) | ||
|
||
override def scalaJSVersion = "1.17.0" | ||
|
||
override def moduleKind = ModuleKind.ESModule | ||
|
||
override def moduleSplitStyle = ModuleSplitStyle.FewestModules | ||
|
||
override def scalaJSExperimentalUseWebAssembly: T[Boolean] = true | ||
|
||
override lazy val millDiscover = { | ||
import mill.main.TokenReaders.given | ||
Discover[this.type] | ||
} | ||
} | ||
|
||
object OldWasmModule extends TestBaseModule with ScalaJSModule { | ||
override def scalaVersion = sys.props.getOrElse("TEST_SCALA_2_13_VERSION", ???) | ||
override def scalaJSVersion = "1.16.0" | ||
|
||
override def moduleKind = ModuleKind.ESModule | ||
override def moduleSplitStyle = ModuleSplitStyle.FewestModules | ||
|
||
override def scalaJSExperimentalUseWebAssembly: T[Boolean] = true | ||
|
||
override lazy val millDiscover = { | ||
import mill.main.TokenReaders.given | ||
Discover[this.type] | ||
} | ||
} | ||
|
||
val millSourcePath = os.Path(sys.env("MILL_TEST_RESOURCE_DIR")) / "wasm" | ||
|
||
val tests: Tests = Tests { | ||
test("should emit wasm") { | ||
val evaluator = UnitTester(Wasm, millSourcePath) | ||
val Right(result) = | ||
evaluator(Wasm.fastLinkJS) | ||
val publicModules = result.value.publicModules.toSeq | ||
val path = result.value.dest.path | ||
val main = publicModules.head | ||
assert(main.jsFileName == "main.js") | ||
val mainPath = path / "main.js" | ||
assert(os.exists(mainPath)) | ||
val wasmPath = path / "main.wasm" | ||
assert(os.exists(wasmPath)) | ||
val wasmMapPath = path / "main.wasm.map" | ||
assert(os.exists(wasmMapPath)) | ||
} | ||
|
||
test("wasm is runnable") { | ||
val evaluator = UnitTester(Wasm, millSourcePath) | ||
val Right(result) = evaluator(Wasm.fastLinkJS) | ||
val path = result.value.dest.path | ||
os.proc("node", "--experimental-wasm-exnref", "main.js").call( | ||
cwd = path, | ||
check = true, | ||
stdin = os.Inherit, | ||
stdout = os.Inherit, | ||
stderr = os.Inherit | ||
) | ||
|
||
} | ||
|
||
test("should throw for older scalaJS versions") { | ||
val evaluator = UnitTester(OldWasmModule, millSourcePath) | ||
val Left(Result.Exception(ex, _)) = evaluator(OldWasmModule.fastLinkJS) | ||
val error = ex.getMessage | ||
assert(error == "Emitting wasm is not supported with Scala.js < 1.17") | ||
} | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters