6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Scala 3 で Web アプリケーションを作ってみよう

Last updated at Posted at 2021-05-31

Scala 3 出ましたね!乗るしかない、このビッグウェーブに!

でも、Play Framework の Scala 3 対応まだだしなぁ、、、と思っているそこのあなた!何も Scala で動く Web フレームワークは Play だけではありません。最近流行りの SpringBoot を使って、 Scala 3 を使った Web アプリケーションを見てみましょう。

結論

最近流行りの SpringBoot の環境構築は Gradle + Kotlin + Vue.js で行われていますが、これを Scala ナイズしましょう。その名も Sbt + Scala + Scala.js です。

sbt new kijuky/springboot-scala.g8

おーっと、これは Scala 2.x ですね。それでは本題の Scala 3 をやってみましょう

sbt new kijuky/springboot-scala.g8 --branch scala3

README.md に書いてあるとおり、下記を実行すると It works が見られます。

docker compose up -d
sbt server/run
open http://localhost:8080/

この環境構築さえできてしまえば、あとは SpringBoot を Scala 3 で書くことができます。

経緯

Gradle プロジェクトを Sbt プロジェクトにした

そもそも最初は Gradle に Scala サポートがあったので、そちらで環境構築していました。ただ、フロントエンドに何使おうかなぁ?と考えたところ、わざわざ Scala 使うんだから、Scala と親和性あるやつがいいよね?と思い、Scala.js を選んでみました。Scala.js も Gradle で環境構築できなくはないですが、Sbt ベースの場合、JavaScript の配置に悩まなくて良くなるし、Sbt だと Scala 3 の環境構築が楽なので、Gradle にはさよならしてもらいました。

参考にした記事

すでに SpringBoot + Kotlin やってる人から見れば、書きっぷりはあんまり変わんないですね。自分はテンプレートエンジンにロジックの少ない mustache が好きなのでそれを入れました。case classからutil.Mapにするおまじないを入れてあげると、なかなか便利にレンダリングしてくれます。

case class ViewModel(
  value: String = "It works!"
) {
  def toMap = {
    import scala.jdk.CollectionConverters._
    this.getClass.getDeclaredFields.map(_.getName).zip(this.productIterator.toList).toMap.asJava
  }
}
@Controller
class IndexController {
  @RequestMapping(path = Array("/"), method = Array(RequestMethod.GET))
  def sample(): ModelAndView =
    new ModelAndView("index").addAllObjects(ViewModel().toMap)
}
index.mustache
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>title</title>
</head>
<body>
{{ value }}
</body>
</html>

Scala.js の導入

次に、フロント用に Scala.js を導入しました。軽く説明すると Scala.js はコンパイルすると1つの main.js になるので、SPA に向いてます。Play を使った Scala.js のマルチプロジェクトの例はよくあるのですが、 SpringBoot でも環境構築はできます。SpringBoot の場合は Akka の設定が役に立ちました。

ほぼほぼ Play と一緒ですが、圧縮に関しては SpringBoot 側に設定があるので、Sbt ではなくそちらに設定します。Scala が書ける JavaScript なんて、トランスパイル結果は膨大になりますから、圧縮は必須ですね。圧縮によって大体サイズが 20% 位になります。

application.yml
server:
  compression:
    enabled: true

そして Scala 3 へ

ここまでくれば、あとは Sbt の scalaVersion を 3.0.0 にするだけです。Play の依存関係のつらみを知っている人にとってはあっけなく感じることでしょう...(インデント構文は趣味です)

さて、ここで残念なお知らせです。Scala.js は Scala 3 に対応しているものの、 Scala.js の各種ライブラリが Scala 3 に対応していません。Scala.js では、基本的な DOM 操作も scalajs-dom のようなライブラリを利用するため、これらのライブラリが使えないとなるとなかなかつらいです...

追記

Scala 3 は Scala 2.13 のバイナリが読めるので、 %%% ではなく % で書けば scalajs-dom も利用できました。やったね!

libraryDependencies += "org.scala-js" % "scalajs-dom_sjs1_2.13" % "1.1.0"
6
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?