文件

§Scala 3 遷移指南

本指南適用於將 Play 應用程式從 Scala 2 遷移到 Scala 3,且您的應用程式必須已至少執行於 Play 2.9(建置於 Akka / Akka HTTP)或 Play 3.0(建置於 Pekko / Pekko HTTP)上。

根據您的程式碼庫,將現有的 Play 應用程式遷移到 Scala 3 可能是一項龐大的任務。我們強烈建議您先遷移到 Play 2.9 或 3.0,同時維持在 Scala 2.13。此方法可確保所有功能都能如預期運作。之後,您就可以轉換到 Scala 3。

§一般

除了此頁面中提到的遷移步驟,其中包含將 Play Framework 應用程式移至 Scala 3 所需的遷移步驟外,還有您想要遵循的一般 Scala 3 資源,以將您的程式碼庫遷移至 Scala 3

§在您的專案中設定 scalaVersion

Scala 和 Java 使用者都必須設定 sbt 以使用 Scala 3。即使您的專案中沒有 Scala 程式碼,Play 本身也會使用 Scala,並且必須設定為使用正確的 Scala 函式庫。

若要在 sbt 中設定 Scala 版本,只需設定 scalaVersion 鍵,例如

scalaVersion := "3.3.3"

重要的是要強調,Play 僅支援 Scala LTS(長期支援) 版本。因此,Scala 3.3 LTS 與後續 LTS 版本之間的任何 Scala 版本,Play 都將不正式支援。然而,使用 Play 搭配此類 Scala 版本可能仍然可行。您可能會對「Scala 3 相容性故事」和 Scala 3.3 發行部落格文章」感興趣。

§搭配 Akka HTTP 10.5 或更新版本使用 Scala 3

本節僅適用於 Play 2.x,但不適用於 Play 3.x。

正如 Play 2.9 重點介紹中所述,Play 2.9 持續提供 Akka 2.6 和 Akka HTTP 10.2,儘管有更新的版本可用。

然而,Akka HTTP 10.2 沒有提供 Scala 3 工件;只有 Akka HTTP 10.5 引入了這些工件。如果您希望使用 Akka HTTP 搭配這些原生 Scala 3 工件,因此想要升級至 Akka HTTP 10.5 或更新版本,您可以使用我們的 Play ScalaPlay Java 更新指南來協助您,這些指南也提供了關於調整哪些設定以搭配 Scala 3 使用 Akka HTTP 10.5 或更新版本的注意事項。我們也強烈建議您檢閱

§某些測試需要 running() wrapper

§使用 specs2

specs2 的 Around 特質 使用了 Scala 的 DelayedInit,而 Scala 3 已放棄此功能(實際上並未移除,只是不再執行任何操作)。很遺憾地,Scala 3 中沒有 DelayedInit 的替代方案。因此,當 使用 specs2 編寫測試時,如果使用

我們必須提出一個解決方案,讓使用者不必徹底修改他們的測試。我們提出的解決方案是將測試包裝在 running() 方法中,因為我們認為這是遷移這些測試最簡單的方法,而且成本不會太高。舉例來說,對於 WithApplication,類似以下的程式碼

"testing some logic" in new WithApplication {
  // <test code>
}

現在需要寫成類似以下的程式碼

"testing some logic" in new WithApplication {
  override def running() = {
    // <test code>
  }
}

使用 wrapper 方法的優點是,我們讓它也能在 Scala 2 中執行,因此即使將 Scala 2 測試包裝在 running() 中,它們仍然會執行,因此此類測試程式碼可以輕鬆地在 Scala 2/3 之間來回切換,而且測試在兩種情況下都能執行(這可能有助於遷移)。

§使用 ScalaTest Plus Play

當使用 ScalaTest 撰寫測試 並利用 AppServerChromeFirefoxHtmlUnitInternetExplorerSafari 時,您需要將測試程式碼包覆在 running() 方法中,才能讓它們在 Scala 3 中運作。這是因為在幕後,ScalaTest 也使用了 DelayedInit,就像前一節所述。例如,使用 App 時,類似下列的程式碼

"testing some logic" in new App(...) {
 // <test code>
}

需要轉換成

"testing some logic" in new App(...) {
  override def running() = {
    // <test code>
  }
}

§字串內插路由 DSL (sird) 匯入

我們必須將一些方法從 隱式類別 play.api.routing.sird.UrlContext 中拆分出來,改用 擴充方法
對您來說,這表示如果您直接匯入了 UrlContext 類別

import play.api.routing.sird.UrlContext

現在您必須改為從 sird 套件匯入所有內容,以確保擴充方法也已匯入

import play.api.routing.sird._

§相依圖表變更

如果你在 Play 應用程式中開始使用 Scala 3,Play specs2 相依性 將不再會拉入 "org.specs2" %% "specs2-mock" 相依性,因為它不再適用於 Scala 3。Play specs2 Scala 3 人工製品取而代之的是依賴 "org.mockito" % "mockito-core" 以直接使用 Mockito,我們認為這是目前為止將你現有的測試程式碼轉換為它的最佳替代方案。
你需要調整你的程式碼,例如,以下是如何使用 Mockito 的程式碼片段

import org.mockito.Mockito._
import org.mockito.ArgumentMatchers._

val userRepository = mock(classOf[UserRepository])
when(userRepository.roles(any[User])).thenReturn(Set(Role("ADMIN")))

下一步:模組目錄


在此文件檔中發現錯誤?此頁面的原始程式碼可以在 這裡 找到。在閱讀 文件檔指南 後,請隨時提交拉取請求。有問題或建議要分享?前往 我們的社群論壇 與社群展開對話。