【问题标题】:Is it possible to ignore JVM-only properties and safely export to JavaScript?是否可以忽略仅 JVM 的属性并安全地导出到 JavaScript?
【发布时间】:2016-02-11 04:21:36
【问题描述】:

我在Play with ScalaJS example 之后有一个基本的项目设置。我发现使用相同模式的其他示例将案例类(模型)与传统上是它们的伴随对象分开。也就是说,案例类将存在于“共享”子项目中,而“伴随对象”(实际上只是一些对象)将存在于“服务器”子项目中。

最好将这两个保存在同一个文件中(即将重要的东西放在真正的伴随对象中),因为在那里放置类型类实例并让它们正确解析非常方便。例如:

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] 的隐式解析将在整个“服务器”子项目中中断,而不会添加显式导入(这会很烦人)。

是否可以在 ScalaJS 导出中显式忽略某些属性,同时仍然允许它们为 JVM 编译?我希望导出 User 案例类,甚至可能导出其伴随对象的其他属性,但仅在 JVM 上存在的其他属性可以在不中断前端的情况下被忽略。

【问题讨论】:

    标签: scala.js


    【解决方案1】:

    我过去解决这个问题的方法(在 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
    

    因此,对于每个单独的编译运行,整个构造只是一个从 trait 继承的对象。源代码来自哪个源目录与编译无关。

    【讨论】:

    • 有趣。不过,我仍然不清楚如何完成这项工作。如果object User存在于共享项目中,而JVM和JS项目都依赖于共享项目,那么如何找到没有循环依赖的trait?
    • 我直接在答案中解决了这个问题。
    • 好吧,这对我来说更有意义。这将是改变我的项目结构以准确适应这个模型的问题。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-17
    相关资源
    最近更新 更多