使用服务器端渲染编写 scala-js 前端框架。无法在服务器上使用 scala-js-dom

问题描述 投票:0回答:1

我正在编写scala-js前端框架,其关键功能是服务器端渲染。这个想法是,有一些组件可以使用

document.createElement
element.appendChild
等操作 dom。在服务器上,我将
HTMLDocument
Element
等子类化,使用可以转换为纯字符串 html 的服务器 dom 实现覆盖它们的方法。所以我向服务器模块添加了
scalajs-dom_sjs
依赖项并尝试这样做。但是
HTMLDocument
Element
以及很可能的其他类在其构造函数中调用了
js.native
,这些类会抛出“使用 JVM 版本的库”异常。这显然不存在。我可以使用另一种方法并实现我自己的 dom 库,但这需要两倍的工作量,因为我必须在服务器和客户端上实现它,而使用第一种方法时我只在服务器上实现一次。

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

scala scala.js server-side-rendering
1个回答
3
投票

禁止这样做的原因是,正如您所注意到的,DOM API 充满了

js.native
。这些类未在 Scala 中实现。它们是浏览器 DOM API 的一部分,而 JVM 上没有相应的 API。您不能在 JVM 上使用
scalajs-dom
中定义的类型并期望它们执行任何有用的操作。这些方法的实现从哪里来?

您确实需要为 JVM 端实现您自己的类似 DOM 的库。如果您不想在客户端“重新实现”它,您可以为您的类重用

org.scalajs.dom
命名空间,并为它们提供与
scalajs-dom
中完全相同的结构和类型(除非它们不会扩展
js.Any 
,显然)。

请注意,这在语义上是可疑的。扩展

js.Any
的类型与普通 Scala 类型的语义不同。你也许能够想出一些“足够兼容”的 API 供正常使用,但这仍然值得怀疑。

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

这正是 Scalatags 所做的。

© www.soinside.com 2019 - 2024. All rights reserved.