【问题标题】:Writing scala-js frontend framework with server-side rendering. Unable to use scala-js-dom on server使用服务器端渲染编写 scala-js 前端框架。无法在服务器上使用 scala-js-dom
【发布时间】:2016-08-29 19:04:07
【问题描述】:

我正在编写 scala-js 前端框架,它的关键特性是服务器端渲染。这个想法是有些组件可以使用document.createElementelement.appendChild 和其他组件来操作 dom。在服务器上,我将子类化HTMLDocumentElement 和其他人,用可以转换为纯字符串 html 的服务器 dom 实现覆盖他们的方法。所以我将scalajs-dom_sjs 依赖添加到服务器模块并尝试这样做。但是HTMLDocumentElement 和最有可能的其他类在其构造函数中调用了js.native,这些调用抛出了“使用库的 JVM 版本”的异常。这显然不存在。我可以使用另一种方式并实现我自己的 dom 库,但这是工作量的两倍,因为我必须在服务器和客户端上实现它,而使用第一种方法我只在服务器上实现一次。

所以我的问题是:为什么如此严格地禁止在服务器上使用 scala-js 库版本,是否有解决方法?

【问题讨论】:

    标签: scala scala.js server-side-rendering


    【解决方案1】:

    禁止这样做的原因是,正如您所注意到的,DOM API 充满了js.natives。这些类没有在 Scala 中实现。它们是浏览器的 DOM API 的一部分,在 JVM 上没有等价物。您不能在 JVM 上使用 scalajs-dom 中定义的类型并期望它们做任何有用的事情。方法的实现从何而来?

    您确实需要为 JVM 端实现自己的类似 DOM 的库。如果您不想在客户端“重新实现”它,您可以为您的类重用 org.scalajs.dom 命名空间,并为它们提供与 scalajs-dom 完全相同的结构和类型(除了它们不会扩展 @987654327 @,显然)。

    请注意,这在语义上是可疑的。扩展 js.Any 的类型与普通 Scala 类型的语义不同。您也许可以想出一些“足够兼容”的 API 以供正常使用,但这仍然值得怀疑。

    通常,为了在服务器和客户端上启用所谓的同构 DOM 操作,需要编写一个与 DOM 无关的交叉编译库。在客户端,它将为实际的 DOM 节点提供“渲染”功能;而在服务器端,它将呈现为要在 HTML 中发送给客户端的字符串。

    这正是Scalatags 所做的。

    【讨论】:

    • 方法的实现从何而来?我会写它们。对于我的目标(服务器端渲染),我不需要实现 ajax 和其他浏览器特定的东西,只需要基本的 dom 操作。
    • 那么我相信你想要的是我在第 2 段中解释的内容,但对第 3 段有所保留。
    • Scalatags 完全可以让你重复使用 dom 和文本后端的模板 lihaoyi.com/scalatags/#Cross-backendCode
    • @LiHaoyi 是的,确实!我没有在 dom 后端部分看到我要查找的内容,因此不再继续查找。
    猜你喜欢
    • 1970-01-01
    • 2021-10-30
    • 2021-11-20
    • 2018-05-02
    • 2017-09-09
    • 2019-04-07
    • 2012-09-24
    • 2015-05-07
    • 2017-07-04
    相关资源
    最近更新 更多