2

I'm writing scala-js frontend framework, the key feature of which is server-side rendering. The idea was that there are components that manipulate dom with document.createElement, element.appendChild and others. On the server I'd subclass HTMLDocument, Element and others, override their methods with server dom implementation that can be converted to plain string html. So I added scalajs-dom_sjs dependency to the server module and tried to do that. But HTMLDocument, Element and most likely other classes have calls to js.native inside their constructors which throw exceptions saying "use JVM version of the library". Which doesn't exist obviously. I could use the other way and implement my own dom library, but that is twice as much work, cause I'd have to implement it on server and client, while using the first approach I'd implement it only once on server.

So my question is: why is it forbidden to use scala-js library versions on server so strictly and is there a work around it?

1 Answer 1

3

The reason this is forbidden is that, as you noticed, the DOM API is full of js.natives. These classes are not implemented in Scala. They are part of the browser's DOM API, which does not have an equivalent on the JVM. You cannot use the types defined in scalajs-dom on the JVM and expect them to do anything useful. Where would the implementations of the methods come from?

You will indeed need to implement your own DOM-like library for the JVM side. If you do not want to "reimplement" it on the client side, you could reuse the org.scalajs.dom namespace for your classes, and give them exactly the same structure and types as in scalajs-dom (except they won't extend js.Any, obviously).

Note that this is semantically dubious. Types extending js.Any do not have the same semantics as normal Scala types. You might be able to come up with some "compatible enough" API for normal use, but it's still dubious.

Usually, to enable so-called isomorphic DOM manipulations on server and client, one would write a DOM-agnostic cross-compiling library. On the client side, it would offer a "rendering" function to actual DOM nodes; and on the server side, it would render to strings to be sent to the client in the HTML.

This is precisely what Scalatags does.

Sign up to request clarification or add additional context in comments.

4 Comments

Where would the implementations of the methods come from? I would write them. For my goal (server side rendering) I don't need to implement ajax and other browser specific stuff, only basic dom manipulations.
Then I believe what you want is what I explain in the 2nd paragraph, with the reservations from the 3rd paragraph.
Scalatags totally lets you re-use templates for dom and text backends lihaoyi.com/scalatags/#Cross-backendCode
@LiHaoyi Yes, indeed! I didn't saw what I was was looking for in the dom backend section and stopped looking further.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.