2016-08-29 2 views
2

Я пишу scala-js frontend framework, ключевой особенностью которого является рендеринг на стороне сервера. Идея заключалась в том, что есть компоненты, которые управляют dom с document.createElement, element.appendChild и другими. На сервере я бы включил подкласс HTMLDocument, Element и другие, переопределив их методы с реализацией сервера dom, которые могут быть преобразованы в простой HTML-код. Поэтому я добавил scalajs-dom_sjs зависимости от серверного модуля и попытался это сделать. Но HTMLDocument, Element и, скорее всего, другие классы имеют вызовы js.native внутри своих конструкторов, которые генерируют исключения, говорящие «используйте JVM-версию библиотеки». Который не существует, очевидно. Я мог бы использовать другой способ и реализовать свою собственную библиотеку dom, но это в два раза больше работы, поэтому я должен был бы реализовать ее на сервере и клиенте, используя первый подход, который я бы реализовал только один раз на сервере.Написание фреймворка scala-js с рендерингом на стороне сервера. Невозможно использовать scala-js-dom на сервере

Так что мой вопрос: почему это запрещено использовать версии библиотеки scala-js на сервере так строго и есть ли работа вокруг него?

ответ

3

Причина, по которой это запрещено, заключается в том, что, как вы заметили, DOM API полон js.native s. Эти классы не реализованы в Scala. Они являются частью API DOM браузера, который не имеет эквивалента на JVM. Вы не можете использовать типы, определенные в scalajs-dom, на JVM и ожидать, что они сделают что-нибудь полезное. Откуда бы были реализованы методы?

Вам действительно понадобится реализовать свою собственную DOM-подобную библиотеку для JVM-стороны. Если вы не хотите «переопределять» его на стороне клиента, вы можете повторно использовать пространство имен org.scalajs.dom для своих классов и дать им точно такую ​​же структуру и типы, что и в scalajs-dom (за исключением случаев, когда они не будут распространяться на js.Any).

Обратите внимание, что это семантически сомнительно. Типы, расширяющие js.Any, не имеют той же семантики, что и обычные типы Scala. Возможно, вы сможете придумать некоторый «совместимый» API для нормального использования, но это все еще сомнительно.

Обычно, чтобы включить так называемые изоморфные манипуляции с DOM на сервере и клиенте, можно было бы написать библиотеку кросс-компиляции DOM-agnostic. На стороне клиента он будет предлагать функцию «рендеринга» фактическим узлам DOM; и на стороне сервера он будет передавать строки для отправки клиенту в HTML.

Это именно то, что делает Scalatags.

+0

Откуда возникнет реализация методов? Я бы написал их. Для моей цели (рендеринга на стороне сервера) мне не нужно реализовывать ajax и другие специфические для браузера вещи, только основные манипуляции с dom. – Yaroslav

+1

Тогда я верю, что вы хотите, что я объясняю во втором абзаце, с оговорками третьего абзаца. – sjrd

+4

Scalatags полностью позволяет вам повторно использовать шаблоны для внутренних и текстовых бэкэндов http://www.lihaoyi.com/scalatags/#Cross-backendCode –

Смежные вопросы