Статьи

Обзор Scala.js с точки зрения разработчика GWT

Этот блог сильно склонен к GWT (и основанным на GWT фреймворкам), но мы помним, что GWT могут быть переняты другими технологиями в будущем, поэтому мы всегда открыты для изучения других платформ / фреймворков. Как говорится, диверсификация снижает риск. Каждый язык программирования, даже самый странный, имеет свой компилятор «to javascript»: https://github.com/jashkenas/coffeescript/wiki/List-of-languages-that-compile-to-JS , поэтому GWT может попытаться выучить учиться у других, чтобы совершенствоваться в будущем. Scala.js всегда сравнивали с GWT, потому что оба они используют язык, основанный на JVM, что подразумевает некоторое сходство в синтаксисе и семантике. Scala.js — это компилятор Scala to javascript, который работает аналогично GWT. Scala.js имеет эквиваленты для вещей, которые делают GWT привлекательным, таких как JsInterop, режим разработки, обрезка, черновая компиляция, элементные, и т. Мы планируем провести сравнение Scala.js с GWT в одном из следующих постов, но перед этим мы хотели бы кратко рассказать о Scala.js и о том, как написать простую программу.

Это Скала, а не Ява

Scala — это объектно-ориентированный язык JVM, который вызвал некоторую шумиху в связи с ориентацией на функциональное программирование и встроенной неизменяемостью. Лично я никогда не писал никаких «настоящих» приложений в Scala, поэтому я действительно не знаю всех тонкостей языка. Кажется, что все, что вы можете сделать со Scala, вы можете сделать с Java 8 и наоборот. Одна вещь, которая привлекает внимание при изучении синтаксических различий, заключается в том, что Scala имеет динамический вывод типов, поэтому типы переменных не объявляются. Это может выглядеть более похожим на javascript и может создавать ощущение, что мы непосредственно программируем на javascript. Документация Scala.js обеспечивает сравнение между Scala и Es6: https://www.scala-js.org/doc/sjs-for-js/es6-to-scala-part1.html.

Настройка проекта

Начальная настройка довольно проста. Существует только один инструмент для сборки scala ( sbt ) и один плагин для Scala.js, поэтому никаких вопросов не возникает. Проект Scala.js не требует специальной структуры, достаточно простой структуры проекта. Требованием для работы с Scala.js является NodeJs. Затем проект можно инициализировать, выполнив команду:

1
sbt new scala/scala-seed.g8

из командной строки. Затем вам будет предложено ввести имя проекта, версию и название организации (эквивалентно groupId в Maven). Затем нам нужно добавить зависимость и конфигурацию Scala.js в наш файл build.sbt (эквивалентный pom.xml). Наш файл build.sbt выглядит примерно так:

01
02
03
04
05
06
07
08
09
10
11
12
13
enablePlugins(ScalaJSPlugin)
 
name := "scalajsdemo"
 
version := "0.1-SNAPSHOT"
 
scalaVersion := "2.11.8"
 
libraryDependencies ++= Seq(
  "org.scala-js" %%% "scalajs-dom" % "0.9.1"
)
 
scalaJSUseMainModuleInitializer := true

Конфигурация минимальна, поэтому никаких больших усилий не требуется.

Использование фреймворка

После настройки проекта все, что нам нужно сделать, это создать класс точки входа, который расширяет объект JSApp.

1
2
3
4
5
object MyForm extends JSApp {
  override def main(): Unit = {
 
  }
}
    1. взаимодействуя с DOM:
      Scala.js имеет довольно обширный API для взаимодействия и манипулирования DOM таким же образом, как и от vanilla JS. На самом деле, это основной фокус Scala.js: по умолчанию нет пользовательских компонентов пользовательского интерфейса для его создания. Например, код для создания кнопки с прослушивателем событий выглядит так:

      1
      2
      3
      4
      5
      6
      val button = document.createElement("button")
          button.textContent = "Click button"
          button.addEventListener("click", { (e0: dom.Event) =>
            println("clicked")
          }, false)
           document.body.appendChild(button)

      Для выполнения HTTP-запроса с использованием XmlHttpRequest код должен выглядеть следующим образом:

      1
      2
      3
      val req = new XMLHttpRequest()
          req.open("GET", "http://www.g-widgets.com/feed/")
          req.setRequestHeader("Access-Control-Allow-Origin", "*")

      Давайте предположим, что мы хотим проанализировать фид G-Widgets Rss и создать список со всеми заголовками, тогда мы бы сделали что-то вроде:

      01
      02
      03
      04
      05
      06
      07
      08
      09
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      val blogPostsListElement = document.createElement("ul")
          req.onload = {(e: Event) =>
            if (req.status == 200) {
              val parser = new DOMParser();
              val doc = parser.parseFromString(req.responseText, "application/xml")
              val titleList = doc.getElementsByTagName("title")
       
       
              for(i <- 0 to titleList.length){
                val listElement = document.createElement("li")
                if(titleList.item(i) != null){
                  listElement.textContent = titleList.item(i).textContent
                  blogPostsListElement.appendChild(listElement)
                }
       
              }
       
            }
          }
          req.send();
       
          document.body.appendChild(blogPostsListElement)
  1. Экспорт в / из Javascript (эквивалент JsInterop):
    Scala.js также имеет возможность экспорта / импорта классов в Javascript с использованием аннотаций. Давайте предположим, что мы хотим использовать служебный объект JSON в нашем коде, один из способов его импорта:

    1
    2
    3
    4
    5
    6
    @js.native
    @JSGlobal
    object JSON extends js.Object {
      def parse(data: String): js.Object = js.native
      def stringify(anobject :js.Object): String = js.native
    }

    Таким же образом мы можем экспортировать некоторый объект, который будет использоваться из скрипта javascript, используя аннотации:

    1
    2
    3
    4
    5
    6
    @JSExportTopLevel("DummyJs")
    class DummyJs(val dummyValue: String) {
     
      @JSExport
       def getTheDummyValue(): String = dummyValue
    }

Компиляция и Devmode

Одна из замечательных особенностей Scala.js — это короткое время компиляции. После изменения кода компиляция занимает не более 9 секунд (для этого простого приложения), чтобы перестроить .js, что довольно обнадеживает и менее разочаровывает. Выбор веб-сервера (при необходимости) остается открытым. Например, может пригодиться сервер с расширением оперативной перезагрузки. Scala.js предлагает два режима компиляции fastOptJS и fullOptJS. при запуске fastOptJS (эквивалентно черновому режиму в GWT) компилятор выполняет меньше оптимизаций и, следовательно, время компиляции короче. Это идеально подходит для развития. fullOptJS, с другой стороны, использует закрывающий компилятор Google для создания очень компактного и оптимизированного файла .js.

Заворачивать

Это было самоуверенное введение в Scala.js. Основными преимуществами, которые может предложить Scala.js, является беспроблемная настройка проекта и быстрая компиляция. GWT более зрелый и более используемый, чем Scala.js, но GWT может извлечь уроки из Scala.js с точки зрения сокращения времени компиляции и шаблонов для настройки проекта. С другой стороны, некоторые сторонники Scala.js не знают об эволюции GWT и иногда дают неточную совокупность возможностей GWT. Например, Грег Дорелл в своем недавнем выступлении на Devoxx заявил, что «GWT не работает», потому что он не обеспечивает хорошие возможности импорта / экспорта в js. Он явно игнорировал тот факт, что GWT также представила JsInterop. GWT по-прежнему выигрывает с точки зрения экосистемы и сообщества. Мы сделаем более подробное сравнение в следующих постах. Подводя итог, можно сказать, что Scala.Js является привлекательной альтернативой разработке веб-приложения. Для разработчиков Java может существовать языковой барьер, но кривая обучения не будет очень крутой, потому что и Java, и Scala являются языками JVM и имеют схожие концепции.

Полный код можно найти здесь: https://github.com/zak905/scalajsdemo

Ссылка: Обзор Scala.js с точки зрения разработчика GWT от нашего партнера по JCG Закарии Амине в блоге G-Widgets .