Scala Advent Calendar 2020 - Qiita 3日目です
ここ2,3年の間にScalaの開発ツールチェーンは進化を続けていて、Scalaの開発体験はめちゃくちゃ良くなってきています。例えば、数年前だと
- IDEは基本的にIntelliJ一択、vimとかemacsで開発環境作れなくもないけどかなり大変
- IntelliJの型チェックがうまく行かなくて、ちょっと複雑なコード書くとコンパイルは通るのに画面が真っ赤になる
- コンパイルが遅い(インクリメンタルビルドしても遅い)
という感じだったのですが、現状はかなり改善されていて
- IntelliJ 以外にも metals という Language Server がかなり使いやすくなっていてあらゆるエディタで簡単にScalaを書けるようになった
- IntelliJ も metals コンパイラ(正確にはビルドサーバー)から直接コンパイルエラーを受け取るのでコンパイル通るのに真っ赤とかはない
- Scalaコンパイラ自体は少しずつ早くなってる。
- sbtのincremental compilerの改善が劇的で、sbtを立ち上げっぱなしにしている場合はかなり開発効率が良い
- フルビルドはやっぱり時間かかる
基本的に OSX / VSCode での環境構築方法を書いていきます。InttelliJ の構築もそのうち書きたい
まだ2020年だけどもうすぐ2021年だし2021年ってタイトルにしちゃった。
- Java のインストール
- sbt のインストール
- 新しくsbtのプロジェクトを作る
- sbt を立ち上げてみる
- REPL を立ち上げてみる
- vscode のセットアップ
- コードフォーマット
- Linter
- Worksheet 機能を使ってみよう
Java のインストール
とりあえずJava11を入れておけば良いと思います。Javaディストリビューションはいろいろあるけどローカルなら何でも良いんじゃないんですかね? oracle とか adoptopenjdk とかで
brew
$ brew cask install java11
# ~/.zshrc なんかに export JAVA_HOME=`/usr/libexec/java_home -v 11`
$ java -version
してなんか出てればOK
HomebrewでインストールできるJDKまとめ(2019年11月時点) - Qiita
java のバージョン切り替え
- アプリケーション開発する分にはjavaのバージョン切り替えたいことはあまりないはず
- 僕は稀にローカル開発環境で異なるjavaを使って動作確認をしたいことがあるので、javaのバージョンをシュシュっと切り替えるために shyiko/jabba: (cross-platform) Java Version Manager を使っています。使い方はREADME読めば分かるはず
- 他には jenv/jenv: Manage your Java environment とか
sbt のインストール
scala の主流なビルドツールである sbt - The interactive build tool をダウンロードします
$ brew install sbt
- ここでダウンロードするsbtのバージョンはそんなに気にしなくて良いです
- ここでダウンロードするsbtはlauncher、プロジェクト毎の設定で実際に利用するsbtのバージョンを指定できる
新しくsbtのプロジェクトを作る
$ sbt new scala/hello-world.g8 [info] welcome to sbt 1.4.4 (AdoptOpenJDK Java 11.0.9) [info] set current project to tanishiking (in build file:/Users/tanishiking/src/github.com/tanishiking/) [info] set current project to tanishiking (in build file:/Users/tanishiking/src/github.com/tanishiking/) A template to demonstrate a minimal Scala application name [Hello World template]: hello Template applied in /Users/tanishiking/src/github.com/tanishiking/./hello
hello
ディレクトリ以下に以下のようなプロジェクトが出来ます。
$ tree . |-- build.sbt |-- project | `-- build.properties `-- src `-- main `-- scala `-- Main.scala
build.sbt
- sbt のビルド設定 sbt Reference Manual — 始める sbt
project/build.properties
sbt.version=1.4.3
みたいなのが書かれてるはず。ここで利用するsbtのバージョンを指定するよ- ルートディレクトリで
sbt
を起動するとここに書かれてるバージョンのsbtがダウンロードされる
sbt を立ち上げてみる
build.sbt
のあるディレクトリに移動してsbt
を起動する
$ sbt [info] [launcher] getting org.scala-sbt sbt 1.4.3 (this may take some time)... ... ... [info] welcome to sbt 1.4.3 (AdoptOpenJDK Java 11.0.9) [info] loading project definition from /Users/tanishiking/src/github.com/tanishiking/hello/project [info] loading settings for project hello from build.sbt ... [info] set current project to hello-world (in build file:/Users/tanishiking/src/github.com/tanishiking/hello/) [info] sbt server started at local:///Users/tanishiking/.sbt/1.0/server/baf7ac7b489b491bdcaa/sock [info] started sbt server sbt:hello-world> sbt:hello-world> compile [info] compiling 1 Scala source to /Users/tanishiking/src/github.com/tanishiking/hello/target/scala-2.13/classes ... update 0s [success] Total time: 3 s, completed Dec 2, 2020, 9:42:12 PM sbt:hello-world> run [info] running Main Hello, World! [success] Total time: 0 s, completed Dec 2, 2020, 9:42:18 PM
- sbt は
$ sbt compile
のように shell から実行することも出来ますが、開発中は sbt は立ち上げっぱなしにしておくことが推奨されています - なぜなら
REPL を立ち上げてみる
sbt を起動して、そこから console
と打ってみましょう
sbt:hello-world> console [info] Starting scala interpreter... Welcome to Scala 2.13.3 (OpenJDK 64-Bit Server VM, Java 11.0.9). Type in expressions for evaluation. Or try :help. scala>
sbt console からなら sbt でダウンロードした依存ライブラリも import 出来たりするので便利
vscode のセットアップ
という感じになっています。metals は scalameta という Scala の解析ツールセットをベースにしたLanguage Server Protocol 実装で IntelliJ Scala に次ぐシェアを誇る (https://scalacenter.github.io/scala-developer-survey-2019/) 開発ツールです。
$ code .
ダウンロードが完了したら build.sbt
や *.scala
ファイルを開いてみましょう。以下のようなポップアップが出てくるので Import build
を押して暫くお待ち下さい。
これでセットアップ完了です
間違えて Import build
しそこねた人は VSCode のコマンドパレットを開いて > metals: Import build
を実行してね。
pro tip
なんかIDEがcomopletionとか返してくれなくなったときは一度 .metals
と .bloop
というディレクトリを削除してVSCodeを再起動しましょう。(IDEのサーバー安定させたいと思っている)
コードフォーマット
scalameta.org を使いましょう
- CLI / sbt plugin / IDE から使えるようになってるけど基本的には sbt plugin か IDE から使うのが個人的におすすめ
- プロジェクトルートに
.scalafmt.conf
を作ってversion=2.7.4
とか書いてください- ここのバージョンはscalafmtのバージョン Releases · scalameta/scalafmt · GitHub を書きます。
VSCode からやる場合
- VSCode のコマンドパレットを開いて
> Format Document
を実行してみましょう。開いているファイルに対してフォーマットが実行されます。 .scalafmt.conf
が存在しない場合は以下のようなポップアップが出てくるのでCreate '.scalafmt.conf'
を押して勝手にファイルを作ってもらったりしましょう。- VSCode の
Format On Save
を有効にすると save 時に勝手にフォーマットしてくれるようになる
sbt から使う場合
- scalameta/sbt-scalafmt: sbt plugin for Scalafmt を使いましょう
project/plugins.sbt
に以下のように書いて sbt を起動します- 紛らわしいのですが、
sbt-scalafmt
のバージョンと、上に書いた scalafmt のバージョンは完全に独立しています。sbt-scalafmt は scalafmt 本体をダウンロードしてきて、それを使ってフォーマットを実行するやつ
- 紛らわしいのですが、
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.2")
sbt を立ち上げ以下のコマンドを打つことで全てのファイルをフォーマットする
sbt:hello-world> scalafmtAll
詳しくは
https://scalameta.org/scalafmt/docs/installation.html#task-keys
Linter
Scala ってデファクトな感じの Linter がないんですよね
一応カスタマイズしやすくて将来的に Scala3 との互換性も保たれそうな Linter(Refactoring tool) としては scalafix が有望、他には WartRemover とかかなぁだけど、そんなに使われてる印象ない
Worksheet 機能を使ってみよう
- worksheet 機能は高級REPLみたいな機能? Scala の標準ライブラリの挙動を確認したりするのに便利
- goto definition などの IDE の機能のついた REPL みたいに考えると良さそう
- 詳しくは https://scalameta.org/metals/docs/editors/vscode.html#worksheets
コマンドパレットから New Scala File
を選び、Worksheets
を選ぶ。
xxx.worksheet.sc
というファイルができるので、そこに適当な scala スクリプトを書いてみよう。以下のような感じでコメントに評価結果が表示される。