以前、ScalaのコードをScala.jsを使ってCloudflareにデプロイした。
上掲の記事を書いた時点では、Scala CLIにまだ慣れていなかったため使っていなかったが、現在はちょっとしたコードのビルドにはScala CLIのほうが便利なので、これを使ってみる。
結論から言うとかなり手軽で便利なので、ちょっとしたサーバみたいな用途で使ってみたいと思う。
まずはpackage.jsonを用意する:
{ "name": "scala-worker", "private": true, "devDependencies": { "esbuild": "^0.27.4", "wrangler": "^4.78.0" }, "scripts": { "build": "scala-cli --power package --js -o worker.tmp.mjs -f src/ && esbuild worker.tmp.mjs --minify --bundle --format=esm --outfile=worker.mjs", "dev": "wrangler dev", "deploy": "wrangler deploy" } }
devDependenciesにesbuildとwranglerを入れている。esbuildはminifyのためだけに用意しているので、無くてもいい。
buildでは、まずscala-cliを利用してソースをmjsにビルドしている。そしてesbuildを利用してminifyしている。
デプロイ用のwrangler.tomlは以下のような感じ。
name = "scala-worker" main = "worker.mjs" compatibility_date = "2024-01-01" [build] command = "npm run build"
最後にsrc/Worker.scalaを用意する:
//> using scala 3.6.4 //> using platform js //> using jsModuleKind es import scala.scalajs.js import scala.scalajs.js.annotation.* object Worker: private def handleFetch( request: js.Dynamic, env: js.Dynamic, ctx: js.Dynamic ): js.Promise[js.Dynamic] = js.Promise.resolve( js.Dynamic.newInstance(js.Dynamic.global.Response)( "Hello from Scala.js on Cloudflare Workers, via Scala CLI / esbuild!" ) ) @JSExportTopLevel("default") val handler: js.Dynamic = js.Dynamic.literal( fetch = js.Any.fromFunction3(handleFetch) )
js.Dynamicが随所に登場しているが、これは「いったんここは型を付けずに頑張ります」くらいの意味で、TypeScriptでいうところのunknownみたいなやつ。
後はpnpm run deployするだけでビルドされてデプロイされる。