§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
- The Scala 3 迁移指南
- The 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 的官方支持。但是,使用这些 Scala 版本与 Play 仍然是可行的。您可能对“Scala 3 兼容性故事”和 Scala 3.3 版本博客文章 感兴趣。
§将 Scala 3 与 Akka HTTP 10.5 或更高版本一起使用
本节仅适用于 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 Scala 或 Play Java 更新指南来实现,这些指南还提供了有关调整哪些设置以在 Scala 3 中使用 Akka HTTP 10.5 或更高版本的说明。我们还强烈建议您查看
§某些测试需要 running()
包装器
§使用 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>
}
}
使用包装方法的一个优势是,我们让它在 Scala 2 中也能工作,因此,即使您将 Scala 2 测试包装在 running()
中,它们也能运行,因此,这样的测试代码可以轻松地在 Scala 2/3 之间来回切换,并且测试在两种情况下都能工作(这可能有助于迁移)。
§使用 ScalaTest Plus Play
当使用 ScalaTest 编写测试 并使用 App、Server、Chrome、Firefox、HtmlUnit、InternetExplorer 或 Safari 时,你需要将测试代码包装在 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")))
下一步:模块目录
发现此文档中的错误?此页面的源代码可以在这里找到 这里。在阅读了 文档指南 后,请随时贡献拉取请求。有任何问题或建议要分享?请访问 我们的社区论坛,与社区进行交流。