【问题标题】:How to provide and consume require.js modules in scala.js (and extending classes)如何在 scala.js 中提供和使用 require.js 模块(以及扩展类)
【发布时间】:2015-09-15 22:48:44
【问题描述】:

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

Atom 是一个基于 web 的编辑器,它使用 js 编写脚本并且基于 node.js。插件/包通过指出一个带有一些特定内容的 javascript 对象来定义它的主要入口点。

我想我应该从简单开始,尝试使用 scala.js 替换我拥有的最简单的咖啡脚本文件:

{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 用于 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()

}

给我编译错误,我无法扩展密封特征 Dynamic。当然。

高度赞赏的任何指针!

【问题讨论】:

  • 嗨维克多,听起来你有两个不同的问题,对吧?我认为如果你将它们分成 SO 帖子,你得到答案的机会会更好。

标签: node.js requirejs atom-editor scala.js


【解决方案1】:

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

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

例如,给定 JS 类 Foo,我可以写 implicit class RichFoo(foo:Foo) { def method1() = { ... } } 这实际上是一个围绕 Foo 的包装器,但是调用代码可以简单地调用 foo.method1() 而无需担心那个细节。

您可以在jquery-facade 中看到这种方法的实际应用,尤其是在JQuery(纯外观)、JQueryTyped(一些针对 JQuery 的调整方法以使其在 Scala 中更好地工作)和JQueryExtensions(一些围绕 JQuery 构建的高级函数)。这些使用package.scala 中的隐式定义组合在一起。就调用代码而言,所有这些都只是 JQuery 上的方法。

【讨论】:

  • 自从我昨天回答这个问题以来,事情已经稍微更新了:有a new proposal to allow you to extend JS classes in Scala.js。请注意,这只是现阶段的一个提议,但现在正在专门寻找评论。因此,虽然目前无法做到这一点,但可能在未来是可能的。
猜你喜欢
  • 2013-04-28
  • 2017-04-10
  • 2021-01-16
  • 1970-01-01
  • 1970-01-01
  • 2011-05-03
  • 2015-07-15
  • 1970-01-01
  • 2015-05-14
相关资源
最近更新 更多