是否可以忽略仅限 JVM 的属性并安全地导出到 JavaScript?
Is it possible to ignore JVM-only properties and safely export to JavaScript?
我在这个 Play with ScalaJS example 之后有一个基本的项目设置。我发现使用相同模式的其他示例会将案例 classes(模型)与其传统上的伴随对象分开。也就是说,案例 class 将存在于 "shared" 子项目中,而 "companion object" (实际上只是一些对象)将存在于 "server" 子项目中。
最好将这两个放在同一个文件中(即将重要的东西放在真正的伴随对象中),因为将类型-class 实例放在那里并让它们解析非常方便适当地。例如:
case class User(id: Int, name: String)
object User {
val default = User(1, "Guest")
// I need this for the back-end, but don't need to export to JS
implicit val reads: Reads[User] = ...
}
不幸的是,这会导致链接错误,因为 Reads
类型仅存在于 JVM 上(只是其中之一)。但是,如果我要将 val reads
移动到另一个文件中,Reads[User]
的隐式解析将破坏整个 "server" 子项目,而不添加显式导入(这会很烦人)。
是否可以显式忽略 ScalaJS 导出中的某些属性,同时仍然允许它们为 JVM 编译?我希望导出 User
案例 class,甚至可能导出其伴随对象的其他属性,但仅可在不中断前端的情况下忽略 JVM 上存在的其他属性。
我过去解决这个问题的方法(在 Scala.js 代码库本身)是通过 PlattformExtensions
混合到交叉编译对象中的特征,但对于 JVM 和 JS 是不同的:
object User extends UserPlattformExtensions {
val default = User(1, "Guest")
}
在您的 JVM 项目中:
trait UserPlattformExtensions {
implicit val reads: Reads[User] = ???
}
在你的 JS 项目中:
trait UserPlattformExtensions
在您的文件组织中(使用标准交叉项目),这将如下所示:
project/
shared/
src/main/
User.scala
jvm/
src/main/
UserPlattformExtensions.scala
js/
src/main/
UserPlattformExtensions.scala
不存在依赖性问题,因为对于编译器来说,源文件的汇编如下:
sources in projectJVM:
shared/src/main/User.scala
jvm/src/main/UserPlattformExtensions.scala
sources in projectJS:
shared/src/main/User.scala
jvm/src/main/UserPlattformExtensions.scala
因此对于每个单独的编译 运行,整个构造只是一个继承自特征的对象。源代码来自哪个源目录与编译无关。
我在这个 Play with ScalaJS example 之后有一个基本的项目设置。我发现使用相同模式的其他示例会将案例 classes(模型)与其传统上的伴随对象分开。也就是说,案例 class 将存在于 "shared" 子项目中,而 "companion object" (实际上只是一些对象)将存在于 "server" 子项目中。
最好将这两个放在同一个文件中(即将重要的东西放在真正的伴随对象中),因为将类型-class 实例放在那里并让它们解析非常方便适当地。例如:
case class User(id: Int, name: String)
object User {
val default = User(1, "Guest")
// I need this for the back-end, but don't need to export to JS
implicit val reads: Reads[User] = ...
}
不幸的是,这会导致链接错误,因为 Reads
类型仅存在于 JVM 上(只是其中之一)。但是,如果我要将 val reads
移动到另一个文件中,Reads[User]
的隐式解析将破坏整个 "server" 子项目,而不添加显式导入(这会很烦人)。
是否可以显式忽略 ScalaJS 导出中的某些属性,同时仍然允许它们为 JVM 编译?我希望导出 User
案例 class,甚至可能导出其伴随对象的其他属性,但仅可在不中断前端的情况下忽略 JVM 上存在的其他属性。
我过去解决这个问题的方法(在 Scala.js 代码库本身)是通过 PlattformExtensions
混合到交叉编译对象中的特征,但对于 JVM 和 JS 是不同的:
object User extends UserPlattformExtensions {
val default = User(1, "Guest")
}
在您的 JVM 项目中:
trait UserPlattformExtensions {
implicit val reads: Reads[User] = ???
}
在你的 JS 项目中:
trait UserPlattformExtensions
在您的文件组织中(使用标准交叉项目),这将如下所示:
project/
shared/
src/main/
User.scala
jvm/
src/main/
UserPlattformExtensions.scala
js/
src/main/
UserPlattformExtensions.scala
不存在依赖性问题,因为对于编译器来说,源文件的汇编如下:
sources in projectJVM:
shared/src/main/User.scala
jvm/src/main/UserPlattformExtensions.scala
sources in projectJS:
shared/src/main/User.scala
jvm/src/main/UserPlattformExtensions.scala
因此对于每个单独的编译 运行,整个构造只是一个继承自特征的对象。源代码来自哪个源目录与编译无关。