node.js – 如何在scala.js中提供和使用require.js模块(以及扩展类)

我正在为Atom.io
https://github.com/ensime/ensime-atom做这个Ensime包,我一直在考虑使用scala.js而不是编写Coffeescript的可能性.

Atom是一个基于Web的编辑器,使用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获取的类的类.

SOOO.

我想我只是使用Dynamic for the require dep,就像我在SO How to invoke nodejs modules from 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()

}

给我编译错误,我无法扩展密封特性动态.当然.

任何指针高度赞赏!

最佳答案 我不是Node本身的专家,但回答你的第一个问题,是的 – 如果你有一个指向JS对象的指针,并且你知道它的类型的细节,你几乎总是可以定义一个外观特征和asInstanceOf使用它.那应该有用.

至于最后一点,你基本上不能在Scala.js中扩展JS类 – 它只是不起作用.我们大多数人解决这个问题的方法是通过定义隐式类或使用隐式def来获得扩展的外观而不实际这样做.

例如,给定JS类Foo,我可以写

    隐式类RichFoo(foo:Foo){
      def method1()= {…}
    }

这实际上是Foo的包装,但调用代码只需调用foo.method1()而不必担心该细节.

您可以在jquery-facade中非常重视这种方法,特别是在JQuery(纯粹的外观),JQueryTyped(一些调整JQuery的方法以使它们在Scala中更好地工作)和JQueryExtensions(一些更高级别的函数)之间的关系JQuery的).这些是使用package.scala中的隐式def保存在一起的.就调用代码而言,所有这些看起来都像JQuery上的方法.

点赞