Lambdaカクテル

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

これだけ読めばOK!Scalaの環境構築2023

自分は、仕事でScalaを数年間・プライベートな経験を含めると10年弱のScalaの経験がある、そこそこの熟練Scalaエンジニアだ。チームにメンバーが入ってきたり他人に勧めるたびにScalaの環境構築を教えている一方、最新の知見を反映した記事が無くて他人に勧めづらかったので、自分が書くことにした。

  • 現在ある記事
    • けっこう古びている
    • 覚えながら書かれていることが多いのでやや曖昧な箇所がある(でもありがとう!)
    • 最新のツールが利用できておらず無駄が多い
    • 網羅的でない
  • 今回目指す内容
    • 最新の知見を活用して最短距離を目指す
    • 何もない状況から一通りのツールが揃う所を目指す

Scalaの環境構築は年を追うごとに簡単になってきているので、大多数の読者は引っかからずに進めるようになっているはず。

Scalaは基本的にJVMで動作する言語だ。このため環境構築にはJVMのセットアップも含まれるのだが、それについてもかなり簡単になっているのでこの記事で扱う。この記事があれば、何も無い状態から開発可能な状態まで持っていけるはずだ。

OSごとの注意点

ScalaはJVM言語なのであまり動作の面で困るポイントはないのだけれど(もちろん、ライブラリがなぜか動かないといったことも殆んどない)、ツールまわりはネイティブコンパイルされていたりするのでちょっと注意が必要な箇所もある。

Windowsの場合

WindowsでScalaを開発する場合はWSLを用いてLinux環境を立ち上げることをおすすめする。というのも、多くのScala関連ツールキットはLinuxかMacを前提として設計されていることが多いためだ。もちろんScalaはJVM言語なのでWindows上でも動作するが、各種ツールの管理のしやすさを加味するとLinux上で開発したほうが良いと思う。

FreeBSDの場合

たまにJDKが入手できないことがあるので注意しよう。

公式のpkgにあるCoursierは古いのであまり動かない。しかし最新のCoursierもFreeBSDをサポートしていないようなので、Linuxのエミュレーションを使うことをおすすめする。

Coursierをインストールする

Scalaコンパイラや関連ツールをインストールするためにはCoursierというほぼ公式*1のツールを使うのが現時点での最適解だ。これを使うことで、ほぼ2ステップでScalaの環境構築は完了する。

CoursierはScalaのソフトウェアやライブラリをダウンロード・インストールするためのコマンドラインツールで、コマンドを使ってツールのインストール・更新・削除・(NPMのnpxのような)直接実行などが可能だ。公式ページには Scala application and artifact manager とか Pure Scala Artifact Fetching などと書かれている。Coursierは、Rustにおけるrustupコマンドに似た立ち位置にある。

Coursierにはメインで使われるネイティブ版と、ネイティブ版が使えない環境のためのJVM版との2種類が提供されており、ネイティブ版のコマンド名はcsだが、JVM版ではcoursierというコマンド名となる。もしJVM版を利用する場合は、csと書いてある箇所はcoursierと読み替えてほしい。

執筆時点でのCoursierの最新版は2.1.7であり、今回はこれを利用している。インストール手順は、Coursier公式ドキュメントの内容に準じている。

Coursierをインストールするには、OS別に以下の手順に従おう。

Linux

マシンがx86-64 / AMD64の場合

一般的なマシンでは以下のコマンドを入力する。

# On x86-64 (aka AMD64)
$ curl -fL "https://github.com/coursier/launchers/raw/master/cs-x86_64-pc-linux.gz" | gzip -d > cs

マシンがARM64の場合

マシンによってはARM64のマシンもある。その場合はダウンロードパスがやや異なる。

# On ARM64
$ curl -fL "https://github.com/VirtusLab/coursier-m1/releases/latest/download/cs-aarch64-pc-linux.gz" | gzip -d > cs

パスを通す

最後にcsを実行可能にし、いつでも呼べるような場所へ移動してパスを通す(パスが通るなら場所はどこでもよい)。

$ chmod +x cs
$ mv cs /usr/local/bin/

macOS

macOSの場合は、Apple Siliconを使っているかどうかでバイナリが異なる。また、Homebrewが利用できる。

マシンがApple Silicon (M1, M2, ...)の場合

$ curl -fL https://github.com/VirtusLab/coursier-m1/releases/latest/download/cs-aarch64-apple-darwin.gz | gzip -d > cs

マシンが非-Apple Siliconの場合

$ curl -fL https://github.com/coursier/launchers/raw/master/cs-x86_64-apple-darwin.gz | gzip -d > cs

パスを通す

ここはLinux版の『パスを通す』と同じなので、そこを参照すること。

Homebrewを使う場合

Apple SiliconではないMacの場合はBrewが便利だ。Apple Siliconの場合はうまくいかないという報告がある。

これだけ読めばOK!Scalaの環境構築2023 - Lambdaカクテル

Apple Silicon Macの場合、brew install coursier/forumulas/coursier だとx86_64のバイナリがインストールされてしまうのでマニュアルインストールの方がよさそう。 <a href="https://github.com/coursier/homebrew-formulas/blob/HEAD/coursier.rb" target="_blank" rel="noopener nofollow">https://github.com/coursier/homebrew-formulas/blob/HEAD/coursier.rb</a>

2023/09/16 21:23
b.hatena.ne.jp

$ brew install coursier/formulas/coursier

Homebrewを使う場合はパスを通す必要はない。

Windowsの場合

Windowsでcsをインストールする場合は、公式インストーラ をダウンロードしてインストールするのが簡単だ。

FreeBSD

FreeBSDではネイティブバイナリが用意されていない。このため、JVM版のcoursierコマンドを利用する。がFreeBSDで入手できるcoursierはかなり古いので、直接Coursierをダウンロードする。

$ fetch https://github.com/coursier/launchers/raw/master/coursier
$ chmod +x coursier
$ mv coursier /usr/local/bin/

がしかし、Coursier自体があまりFreeBSDに対応していないようで、あまりサポートされていない。Linuxなどをなんらかの方法で仮想化して利用すると良さそう。

JVMと各種ツールをセットアップする

CoursierにScalaまわりの一式をセットアップしてもらうには、cs setupを実行する。これだけで標準的なツールキットが導入され、環境構築は完了する。

$ cs setup

すると、JVMがインストールされていない場合はインストールしてよいか訊かれるので、それでよければyを入力してエンターを押下する。

Checking if a JVM is installed
No JVM found, should we try to install one? [Y/n] y

すると、適当なJVMをインストールしてもらえる。筆者の執筆時はopenjdk version "11.0.20"がインストールされた。

既にJVMがセットアップされていたり、別の手段で管理している場合はnを入力すればよい。筆者は普段はasdfを使ってJVMを管理している。

次に、パスなどを通すために.profileをいじって良いかなどと訊かれるので、基本的にyと答える。

Should we update ~/.profile? [Y/n] y
Should we add ~/.local/share/coursier/bin to your PATH via ~/.profile? [Y/n] y

するとScala関連ツールキットのうち、定番のものが自動的にインストールされて使えるようになる。

Checking if the standard Scala applications are installed
  Installed ammonite
  Installed cs
  Installed coursier
  Installed scala
  Installed scalac
  Installed scala-cli
  Installed sbt
  Installed sbtn
  Installed scalafmt

最後に.profileを再読み込みして各種ツールを実行できるようにする。

$ source ~/.profile

ところで、Scalaは3つの方法で開発できる。

  • Scala CLIなどが提供するREPL
  • LLライクな手軽さで単独ファイルで動作するScala Script
  • ディレクトリの中にプロジェクトを作成して開発するsbtやmillといったビルドツール

今回は試しに、Scala Scriptを実行したりREPLを動かせるツールのScala CLIを実行してHello, Worldしてみよう。

$ scala-cli
Downloading Scala 3.3.0 compiler
Welcome to Scala 3.3.0 (11.0.20, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.
scala> println("Hello, World!")
Hello, World!

おめでとう。初めてのScalaプログラムを実行できた。

Scala CLIは、Ctrl+Dを押下するか、Ctrl+Cを押下するか、:quit (:qでもよい)と入力することで終了できる。

scala> :q
$

Scalaを書くときは、小さい規模から順にREPL→Scala Script→プロジェクト管理を使うことになる。

Coursierが標準でインストールするツール

各種インストールされた各種ツールについて、軽く説明しておこう。とくに重要なものには⭐をつけておいた。

  • ammonite
    • ScalaのREPL。ammで起動する。Scala CLIが上位互換なので最近はScala CLIを使えばよい。
  • ⭐cs
    • Coursierはcsコマンド自身を自分で管理するので、cs update csなどとするとアプデ可能。
  • coursier
    • CoursierはcsのJVM版であるcoursierコマンドも一応インストールしてくれる。
  • scala
    • Scalaのランナー。.scalaファイルを渡すとスクリプト的に実行してくれる。
    • 単独で実行するとScala CLI的にREPLが開く。
  • scalac
    • Scalaコンパイラ。実行すると渡したファイルをクラスファイルにコンパイルしてくれるが、一般ユーザが直接使うことはほぼない。
  • ⭐scala-cli
    • Scala CLI。Scalaのランナー。将来的にscalaコマンドを置き換える予定なので、REPLなどを使いたかったら基本的にこちらを使うとよい。
  • ⭐sbt
    • Scalaのビルドツール。複数ファイルのScalaコードを書く際や複雑なコンパイル手順が必要な場合は、ビルドツールを使うことになる。
  • sbtn
    • sbtをバックグラウンドで起動して起動時間を早くしようという野心的なソフトウェアだが、まだ実験的。
  • ⭐scalafmt
    • Scalaのフォーマッタ/Linter。
    • 最近は頼めばIDEが自動的にこれを呼び出してくれるので、直接呼ばなくても良い。

うち、csとScala CLI、sbtの初歩についても説明しておく。

csの初歩

有名なScalaのツールはcs installを用いてインストールできる。

# ビルドツールMillをインストールする
$ cs install mill

パスも自動的に通るので便利だ。

インストール可能なツールは、cs searchと入力すると得られる。

ツールはcs update <名前>で更新可能だ。

ツールを削除するには、cs uninstall <名前>とすればよい。

面白い機能として、Mavenにアップロードされているアプリケーションを直接実行するlaunchサブコマンドがあることだ。例えば、以下のコマンドはWindymeltの誕生日が表示されるだけのコマンドだ:

$ cs launch io.github.windymelt::happy-birthday::0.0.1

Scala CLIの初歩

Scala CLIは、ファイル1つで完結しそうなことなら大体なんでもやってくれるツールだ。

REPL

scala-cliを単独で実行すると、REPLが起動する。REPLではScalaのコードを直接書いて試すことができる。

scala> val xs = Seq(1,2,3)
val xs: Seq[Int] = List(1, 2, 3)

scala> 42
val res0: Int = 42

scala> xs.map(_ + res0)
val res1: Seq[Int] = List(43, 44, 45)

上に示しているように、特に変数代入しなくとも自動的にres0res1...のように値を保存してくれるので試行錯誤しやすい。

Scalaのバージョンは-Sオプションで指定可能だ。特に指定しない場合、現在はScala 3.3.0が利用される。

$ scala-cli -S 2
Welcome to Scala 2.13.11 (OpenJDK 64-Bit Server VM, Java 11.0.20).
Type in expressions for evaluation. Or try :help.

scala>

Scala Scriptの実行

Scala CLIは、.sc.scala.scで終わるファイル(Scala Script)を実行する能力を持っている。Scala Scriptは通常の.scalaファイルと違い、何でもトップレベルに書くことができる。

// script.sc
// トップレベル記述
val x = 42

println(x * 2)
$ scala-cli script.sc
(初回はコンパイルやダウンロードで少し待つ)
84

また、Scala Scriptは引数を受け取ったり、処理系のバージョンを指定したり、依存するライブラリを指定して自動的にScala CLIに用意させたり、シェルスクリプトのように直接実行できるshebangに対応したりしている。

#!/usr/bin/env -S scala-cli shebang -S 3
//> using dep com.github.nscala-time::nscala-time:2.32.0
// ↑ライブラリ依存を定義している
// 一番上の行は直接呼べるようにするためのshebang

import com.github.nscala_time.time.Imports._

println(DateTime.now().toString)

// 引数がargsに入っている
println(s"you passed ${args.toSeq}")
$ chmod +x script.sc
$ ./script.sc 1 2 3
Compiling project (Scala 3.3.0, JVM)
Compiled project (Scala 3.3.0, JVM)
2023-09-14T16:15:46.204Z
you passed ArraySeq(1, 2, 3)

より詳しくは、以下の記事を参考。

tanishiking24.hatenablog.com

blog.3qe.us

zenn.dev

sbtの初歩

sbtはScalaのビルドツールで、複数ファイルにまたがる中規模以上の開発のために必要だ。

sbtはプロジェクトテンプレートからプロジェクトを作成する機能があるので、初心者はこれを使うとよい:

# GitHubのscala/scala3.g8テンプレートからプロジェクトディレクトリを生成する
$ sbt new scala/scala3.g8
A template to demonstrate a minimal Scala 3 application 

name [Scala 3 Project Template]: my-project (入力する)

Template applied in /root/./my-project

ちなみにsbt newを単独で起動するだけでも便利なメニューが表示される:

$ sbt new

Welcome to sbt new!
Here are some templates to get started:
 a) scala/toolkit.local               - Scala Toolkit (beta) by Scala Center and VirtusLab
 b) typelevel/toolkit.local           - Toolkit to start building Typelevel apps
 c) sbt/cross-platform.local          - A cross-JVM/JS/Native project
 d) scala/scala3.g8                   - Scala 3 seed template
 e) scala/scala-seed.g8               - Scala 2 seed template
 f) playframework/play-scala-seed.g8  - A Play project in Scala
 g) playframework/play-java-seed.g8   - A Play project in Java
 i) softwaremill/tapir.g8             - A tapir project using Netty
 m) scala-js/vite.g8                  - A Scala.JS + Vite project
 n) holdenk/sparkProjectTemplate.g8   - A Scala Spark project
 o) spotify/scio.g8                   - A Scio project
 p) disneystreaming/smithy4s.g8       - A Smithy4s projectScalaは2つの方法で開発できる。

- LLライクな手軽さで単独ファイルで動作するScala Script
- プロジェクト用ディレクトリで動作するsbtプロジェクト
 q) quit
Select a template:

プロジェクトディレクトリの中でsbt runを実行するとプロジェクトを実行できる。

$ sbt run
[info] running hello 
Hello world!
I was compiled by Scala 3. :)
[success] Total time: 9 s, completed Sep 14, 2023, 4:37:09 PM
$

今回は環境構築の記事なので、sbtの詳しい使い方は割愛する。

嬉しいことに、sbtには公式日本語ドキュメントがあるのでこれを参照するとよい。

www.scala-sbt.org

IDE

ScalaにはMetalsというLSPがあるので、LSPをサポートする好みのエディタで開発できる。今のところ、これを使うのが最も確実にScalaの型の恩恵を受けられる方法だ。これは好みだが、好みがなければとりあえずVSCodeを選べばよいだろうと思う。IntelliJも良いが、独自のプレゼンテーションコンパイラを使っているため、複雑なプロジェクトだとうまく動作しないことがある。中規模までのプロジェクトであれば問題ないと思う。

VSCodeはScala (Metals) 拡張機能をインストールすることで自動的にMetalsが導入され、コードの候補表示や補完が動作するようになる。

marketplace.visualstudio.com

scalameta.org

便利なサイト

発展的な内容として、いくつかのサイトをおすすめする。

Jump into

ここまで完了した人は以下の内容に足を運んでみても良いかもしれない。

  • sbtでJARファイルを生成するには?
  • Scala Nativeを利用してJavaに依存しないバイナリファイルを出力するには?
  • Scala.jsを利用してブラウザ上でScalaを動作させるには?
  • ScalaのライブラリをMaven Central Repositoryに公開するには?
  • sbtのほかにもビルドツールってあるの?
  • Sparkを使ってみたいんだけど?

Community

日本語話者のためのScala Discordサーバを運営しています。ゆるいイメージでやりたいので、Scalaわいわいランドという名前です。

*1:CoursierはScala Centerの支援を受けている

Webアプリケーション開発関連の記事を投稿しています.読者になってみませんか?