1. 函式庫相依性

函式庫相依性 

此頁面假設您已閱讀先前的「入門」頁面,特別是建置定義作用域任務圖

可以使用兩種方式加入函式庫相依性

  • 未受管理的相依性是放入 lib 目錄中的 jar 檔
  • 受管理的相依性是在建置定義中設定,並從儲存庫自動下載

未受管理的相依性 

大多數人使用受管理的相依性,而非未受管理的相依性。但剛開始時,未受管理的相依性可能較為簡單。

未受管理的相依性運作方式如下:將 jar 檔加入 lib,它們就會被放置在專案類別路徑中。僅此而已!

您也可以將測試 jar 檔(例如ScalaCheckSpecs2ScalaTest)放入 lib 中。

lib 中的相依性會出現在所有類別路徑中 (適用於 compiletestrunconsole)。如果您只想變更其中一個的類別路徑,您可以調整例如 Compile / dependencyClasspathRuntime / dependencyClasspath

使用未受管理的相依性時,不需要在 build.sbt 中新增任何內容,但如果您想要使用不同於 lib 的目錄,您可以變更 unmanagedBase 金鑰。

若要使用 custom_lib 而非 lib

unmanagedBase := baseDirectory.value / "custom_lib"

baseDirectory 是專案的根目錄,因此在這裡,您正在使用特殊 value 方法根據 baseDirectory 來變更 unmanagedBase,如任務圖中所述。

還有一個 unmanagedJars 任務,會列出 unmanagedBase 目錄中的 jar 檔。如果您想要使用多個目錄或執行其他複雜操作,您可能需要將整個 unmanagedJars 任務替換為執行其他操作的任務,例如,無論 lib 目錄中的檔案為何,都要清空 Compile 組態的清單

Compile / unmanagedJars := Seq.empty[sbt.Attributed[java.io.File]]

受管理的相依性 

sbt 使用Coursier 來實作受管理的相依性,因此如果您熟悉 Coursier、Apache Ivy 或 Maven,您將不會遇到太多麻煩。

libraryDependencies 金鑰 

大多數時候,您可以簡單地在設定 libraryDependencies 中列出您的相依性。也可以撰寫 Maven POM 檔案或 Ivy 組態檔案,在外部設定您的相依性,並讓 sbt 使用這些外部組態檔案。您可以在這裡了解更多資訊。

宣告相依性看起來像這樣,其中 groupIdartifactIdrevision 是字串

libraryDependencies += groupID % artifactID % revision

或像這樣,其中 configuration 可以是字串或 Configuration 值 (例如 Test)

libraryDependencies += groupID % artifactID % revision % configuration

libraryDependenciesKeys 中宣告,如下所示

val libraryDependencies = settingKey[Seq[ModuleID]]("Declares managed dependencies.")

% 方法會從字串建立 ModuleID 物件,然後您將這些 ModuleID 加入 libraryDependencies

當然,sbt (透過 Coursier) 必須知道從哪裡下載模組。如果您的模組在 sbt 隨附的預設儲存庫中,這將會正常運作。例如,Apache Derby 在標準 Maven2 儲存庫中

libraryDependencies += "org.apache.derby" % "derby" % "10.4.1.3"

如果您在 build.sbt 中輸入該內容,然後輸入 update,sbt 應該會將 Derby 下載到Coursier 快取。(順便說一下,updatecompile 的相依性,因此大多數時候不需要手動輸入 update。)

當然,您也可以使用 ++= 一次加入相依性清單

libraryDependencies ++= Seq(
  groupID % artifactID % revision,
  groupID % otherID % otherRevision
)

在極少數情況下,您可能會發現需要使用 :=libraryDependencies

使用 %% 取得正確的 Scala 版本 

如果您使用 organization %% moduleName % version 而非 organization % moduleName % version (差異在於 organization 之後的雙 %%),sbt 會將您專案的二進位 Scala 版本加入構件名稱。這只是一個捷徑。您可以在沒有 %% 的情況下撰寫此內容

libraryDependencies += "org.scala-stm" % "scala-stm_2.13" % "0.9.1"

假設您建置的 scalaVersion2.13.12,則以下內容相同 (請注意 "org.scala-stm" 之後的雙 %%)

libraryDependencies += "org.scala-stm" %% "scala-stm" % "0.9.1"

其想法是,許多相依性會針對多個 Scala 版本進行編譯,而您會希望取得與您的專案相符的版本,以確保二進位相容性。

如需更多詳細資訊,請參閱跨版本建置

Ivy 修訂版本 

organization % moduleName % version 中的 version 不必是單一固定版本。Ivy 可以根據您指定的限制,選取模組的最新修訂版本。您可以指定 "latest.integration""2.9.+""[1.0,)",而不是像 "1.6.1" 這樣的固定修訂版本。如需詳細資訊,請參閱Ivy 修訂版本文件。

有時會使用 Maven「版本範圍」來指定相依性(傳遞或其他),例如 [1.3.0,)。如果建置中宣告了相依性的特定版本,且該版本符合範圍,則 sbt 將會使用指定的版本。否則,Coursier 可能會連上網際網路來尋找最新版本。這會導致令人驚訝的行為,即有效版本會隨著時間不斷變更,即使有指定符合範圍條件的函式庫版本。

如果建置符合,Maven 版本範圍將會替換為其下限,以便在相依性圖表中找到符合的版本時將會使用該版本。您可以使用 JVM 旗標 -Dsbt.modversionrange=false 來停用此行為。

解析器 

並非所有套件都位於相同的伺服器上;sbt 預設會使用標準 Maven2 儲存庫。如果您的相依性不在預設儲存庫之一,您必須加入解析器以協助 Ivy 找到它。

若要新增其他儲存庫,請使用

resolvers += name at location

在兩個字串之間使用特殊 at

例如

resolvers += "Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots"

resolvers 金鑰在Keys 中定義,如下所示

val resolvers = settingKey[Seq[Resolver]]("The user-defined additional resolvers for automatically managed dependencies.")

at 方法會從兩個字串建立 Resolver 物件。

如果將本機 Maven 儲存庫新增為儲存庫,sbt 可以搜尋本機 Maven 儲存庫

resolvers += "Local Maven Repository" at "file://"+Path.userHome.absolutePath+"/.m2/repository"

或為了方便起見

resolvers += Resolver.mavenLocal

如需定義其他類型儲存庫的詳細資訊,請參閱解析器

覆寫預設解析器 

resolvers 不包含預設解析器;僅包含您的建置定義所新增的其他解析器。

sbt 會將 resolvers 與一些預設儲存庫合併,以形成 externalResolvers

因此,若要變更或移除預設解析器,您需要覆寫 externalResolvers,而不是 resolvers

每個組態的相依性 

通常,相依性會由您的測試程式碼使用 (在 src/test/scala 中,由 Test 組態編譯),而不是您的主要程式碼。

如果您希望相依性僅出現在 Test 組態的類別路徑中,而不是 Compile 組態的類別路徑中,請加入 % "test",如下所示

libraryDependencies += "org.apache.derby" % "derby" % "10.4.1.3" % "test"

您也可以使用 Test 類型安全的配置版本,如下所示:

libraryDependencies += "org.apache.derby" % "derby" % "10.4.1.3" % Test

現在,如果您在 sbt 互動式提示符下輸入 show Compile/dependencyClasspath,您應該看不到 derby jar。但如果您輸入 show Test/dependencyClasspath,您應該會在列表中看到 derby jar。

通常,測試相關的依賴項,例如 ScalaCheckSpecs2ScalaTest,會使用 % "test" 來定義。

有關程式庫依賴項的更多詳細資訊和技巧,請參閱此頁面