LoginSignup
4
1

More than 3 years have passed since last update.

sbt マルチプロジェクト構成を試してみた話

Last updated at Posted at 2020-12-06

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 型の値を定義できるので、下記のようになります。

build.sbt
 // 複数プロジェクトで共通のセッティングをしたい場合、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 プロジェクトへの依存を定義してみます

build.sbt
 // 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 という名前で作ってみました。

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 してみます。

main/src/main/scala/main
 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 について深く知らずに使ってたなあ、としみじみ思ったので今回触ってみて色々気づきがあってよかったです。)

4
1
0

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
4
1