sbt マルチプロジェクト構成を試してみた話
この記事について
ふと、「そういえば sbt のマルチプロジェクト構成ってやったことないな・・・」と思ったのでやってみた話です。
マルチプロジェクト構成で、サブプロジェクトから別のサブプロジェクトのコードを利用するところまでやってみました。
参考サイト
あらかじめやっておくこと
JDK / sbt のインストールは行っておきます
ディレクトリ構成
下記のようなディレクトリ構成で進めようと思います
root
- common // 共通処理
- main // common を参照して実行する処理
- build.sbt // ビルド定義
common に共通処理を定義して、
common の処理を main プロジェクトで利用してみます。
プロジェクトをまとめる build.sbt の大枠を作ってみる
プロジェクトのルートディレクトリにサブプロジェクトを含めたビルド定義ファイル build.sbt
を用意します。
今回は、 common
/ main
という 2 つのサブプロジェクトを作りたいのでこの 2 つを定義してみます。
project in file("サブプロジェクトのディレクトリ名")
で Project 型の値を定義できるので、下記のようになります。
// 複数プロジェクトで共通のセッティングをしたい場合、ThisBuild / で定義できる
ThisBuild / version := "0.1.0-SNAPSHOT"
// commonSettingsという名前のセッティング Seq を作り、各プロジェクトの .settings に渡すことで共通の設定を行うこともできる
lazy val commonSettings = Seq (
scalaVersion := "2.13.3"
)
// common サブプロジェクトの定義
lazy val common = (project in file("common"))
.settings(
commonSettings
)
// main サブプロジェクトの定義
lazy val main = (project in file("main"))
.settings(
commonSettings
)
別のプロジェクトのソースに依存する記述を build.sbt に追加する
依存関係をどう表現するのかについて sbt公式 クラスパス依存性 をみると、
別のプロジェクトへの依存関係は dependsOn
メソッドを使用することで実現できそうです。
ということで、build.sbt
の main プロジェクトでこの dependsOn
メソッドを使用し、common プロジェクトへの依存を定義してみます
// main サブプロジェクトの定義
lazy val main = (project in file("main"))
.dependensOn(common) // common プロジェクトへの依存関係を定義
.settings(
commonSettings
)
これで main プロジェクト から common プロジェクトのソースを参照する準備ができました。
ということで実際に参照してみます。
実際に main プロジェクトから common プロジェクトのソースを利用してみる
common プロジェクトにクラスを追加
適当なクラスを common プロジェクトに追加します。
今回は common/src/main/scala/common/model
下に Coffee.scala
という名前で作ってみました。
package common.model
case class Coffee(name:String, price:Int)
次にこのクラスを main プロジェクトの方から参照してみます。
main プロジェクトから参照してみる
適当なクラスを main プロジェクトに追加します。
実行したいので App
を継承した object にしておきます。
別のプロジェクトの場合でも、package.class 名で import できそうなので、
common プロジェクトの Coffee クラスも import してみます。
package main
// 別のプロジェクトでも package.class名で import
import common.model.Coffee
object MainApplication extends App {
val coffeeList = List(Coffee("Blue Mountain", 650), Coffee("Kilimanjaro", 600))
println(coffeeList)
}
(作って気づいたんですが、パスに main が入りすぎてて気持ち悪いですね。)
実行
では、実際に実行して確認してみます。
sbt でプロジェクトを指定して実行する場合は、sbt プロジェクト名/コマンド
で実行できます。
(sbt 起動しっぱなしなら sbt 内で プロジェクト名/コマンド
で)
今回は、main プロジェクトをただ実行したいので、下記コマンドで実行します。
main プロジェクト実行コマンド : sbt main/run
実行結果をみてみると、、、
[info] running main.MainApplication
List(Coffee(Blue Mountain,650), Coffee(Kilimanjaro,600))
無事参照できてそうでした!!
まとめ
共通の処理を切り出したり、機能で分割するのに、マルチプロジェクトはとても良さそうでした。
色々フレームワークやライブラリ触るときにプロジェクト作りまくってたのですが、それも整理できそうで嬉しいです。
(個人的に Giter8 テンプレートを使うことが多かったのですが、
あまり sbt について深く知らずに使ってたなあ、としみじみ思ったので今回触ってみて色々気づきがあってよかったです。)