Как предоставлять и использовать модули require.js в scala.js (и расширяющие классы)

Я делаю этот пакет Ensime для Atom.io https://github.com/ensime/ensime-atom и я думал о возможности использовать scala.js вместо написания Coffeescript.

Atom — это веб-редактор, написанный с помощью js и основанный на node.js. Плагин/пакет определяет свою основную точку входа, указывая объект javascript с несколькими специфическими параметрами.

Я решил, что должен начать с простого и попробовать использовать scala.js, заменив самый простой файл coffeescript, который у меня есть:

{View} = require 'atom-space-pen-views'
# View for the little status messages down there where messages from Ensime server can be shown
module.exports =
  class StatusbarView extends View
    @content: ->
      @div class: 'ensime-status inline-block'

    initialize: ->

    serialize: ->

    init: ->
      @attach()

    attach: =>
      statusbar = document.querySelector('status-bar')
      statusbar?.addLeftTile {item: this}

    setText: (text) =>
      @text("Ensime: #{text}").show()

    destroy: ->
      @detach()

Как видите, это экспортирует модуль require.js и является классом, расширяющим класс, полученный с помощью require.

Тааак.

Я думаю, что просто использовал бы Dynamic для требуемой зависимости, как я видел на SO Как вызывать модули nodejs из scala.js?:

import js.Dynamic.{global => g}
import js.DynamicImplicits._

private[views] object SpacePen {
  private val spacePenViews = require("atom-space-pen-views")
  val view = spacePenViews.view
}

Но если бы я хотел ввести суперкласс, мог бы я просто создать фасадную черту и сделать asInstanceOf?

Во-вторых, мне интересно, как я могу экспортировать свой класс как модуль узла. Я нашел это:

https://github.com/rockymadden/scala-node/blob/master/main/src/main/coffeescript/example.coffee

Это правильный путь? Нужно ли делать песочницу? Нельзя ли просто получить moduleimported из глобального и написать module.exports = _some_scala_object_?

Мне также интересно, как я могу расширить существующие классы js. Та же проблема, что и здесь, но я не очень понимаю ответ:

https://groups.google.com/forum/#!topic/scala-js/l0gSOSiqubs

My code so far:
private[views] object SpacePen {
  private val spacePenViews = js.Dynamic.global.require("atom-space-pen-views")
  type View = spacePenViews.view
}

class StatusBarView extends SpacePen.View  {
  override def content =
    super.div()

}

дает мне ошибки компиляции, из-за которых я не могу расширить запечатанную черту Dynamic. Конечно.

Любые указатели высоко ценятся!


person Viktor Hedefalk    schedule 29.06.2015    source источник
comment
Привет, Виктор, похоже, у тебя два разных вопроса, верно? Я думаю, что ваши шансы получить на них ответы будут выше, если вы разделите их на сообщения SO.   -  person Nightscape    schedule 01.07.2015


Ответы (1)


Я не особо разбираюсь в Node как таковом, но отвечая на ваш первый вопрос, да, если у вас есть указатель на объект JS и вы знаете детали его типа, вы практически всегда можете определить свойство фасада и asInstanceOf, чтобы использовать его. Это должно сработать.

Что касается последнего бита, вы в принципе не можете расширять классы JS в Scala.js — это просто не работает. Большинство из нас обходит это путем определения неявных классов или использования неявных определений, чтобы получить видимость расширения, не делая этого на самом деле.

Например, имея JS-класс Foo, я могу написать implicit class RichFoo(foo:Foo) { def method1() = { ... } } На самом деле это оболочка вокруг Foo, но вызывающий код может просто вызвать foo.method1(), не беспокоясь об этой детали.

Вы можете увидеть этот подход в действии в jquery-facade, особенно в отношениях между JQuery ( чистый фасад), JQueryTyped (некоторые подправленные методы над JQuery, чтобы они лучше работали в Scala) и JQueryExtensions (некоторые высокоуровневые функции, построенные на основе JQuery). Они удерживаются вместе с помощью неявных определений в package.scala. Что касается вызывающего кода, все они выглядят просто как методы в JQuery.

person Justin du Coeur    schedule 12.07.2015
comment
И так как я ответил на это вчера, ситуация немного изменилась: появилось новое предложение позволяют расширять классы JS в Scala.js. Имейте в виду, что на данном этапе это всего лишь предложение, но сейчас оно специально ищет комментарий. Таким образом, пока это невозможно сделать в настоящее время, это может стать возможным в будущем. - person Justin du Coeur; 13.07.2015