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

时间:2016-08-29 08:36:42

标签: scala scala.js serverside-rendering

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

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

1 个答案:

答案 0 :(得分:3)

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

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

请注意,这在语义上是可疑的。扩展js.Any的类型与普通的Scala类型没有相同的语义。你可能能够提出一些足够的兼容性"正常使用的API,但它仍然可疑。

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

这正是Scalatags所做的。