Lambdaカクテル

京都在住Webエンジニアの日記です

Invite link for Scalaわいわいランド

Scalaコードを最速でCloudflare Workerにデプロイする

以前、ScalaのコードをScala.jsを使ってCloudflareにデプロイした。

blog.3qe.us

上掲の記事を書いた時点では、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"
  }
}

devDependenciesesbuildwranglerを入れている。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するだけでビルドされてデプロイされる。

https://scala-worker.windymelt.workers.dev

★記事をRTしてもらえると喜びます
Webアプリケーション開発関連の記事を投稿しています.読者になってみませんか?