2

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

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

4

1 回答 1

3

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

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

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

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

这正是Scalatags所做的。

于 2016-08-29T11:04:07.123 回答