如何在 scala.js 中提供和使用 require.js 模块(并扩展 类)
How to provide and consume require.js modules in scala.js (and extending classes)
我正在为 Atom.io https://github.com/ensime/ensime-atom 做这个 Ensime 包,我一直在考虑使用 scala.js 而不是编写 Coffeescript 的可能性。
Atom 是一个基于 Web 的编辑器,它使用 js 编写脚本并且基于 node.js。 plugin/package 通过指出具有一些特定的 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 模块,并且是一个 class 扩展了一个 class 并通过 require 获取。
太棒了。
我在想我会像我在 SO :
上看到的那样使用 Dynamic 作为需求 dep
import js.Dynamic.{global => g}
import js.DynamicImplicits._
private[views] object SpacePen {
private val spacePenViews = require("atom-space-pen-views")
val view = spacePenViews.view
}
但是如果我想输入 super-class,我可以做一个 facade-trait 然后做 asInstanceOf 吗?
其次,我想知道如何将 class 导出为节点模块。我发现了这个:
https://github.com/rockymadden/scala-node/blob/master/main/src/main/coffeescript/example.coffee
这是正确的方法吗?我需要做沙盒吗?我不能直接从全局导入 module
并写 module.exports = _some_scala_object_
吗?
我也想知道如何扩展现有的 js classes。和这里问的问题一样,但是我不太明白答案:
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。当然可以。
非常感谢任何指点!
我本身并不是 Node 的专家,但要回答你的第一个问题,是的——如果你有一个指向 JS 对象的指针,并且你知道它的类型的详细信息,你几乎总是可以定义外观特征和 asInstanceOf 以使用它。应该可以。
至于最后一点,您基本上无法在 Scala.js 中扩展 JS classes -- 它根本不起作用。我们大多数人解决这个问题的方法是通过定义隐式 classes 或使用隐式 def 来获得 外观 扩展而不实际这样做。
例如,给定 JS class Foo,我可以写
implicit class RichFoo(foo:Foo) {
def method1() = { ... }
}
这实际上是 around Foo 的包装器,但是调用代码可以简单地调用 foo.method1() 而不必担心那个细节。
您可以在 jquery-facade, particularly in the relationship between JQuery (the pure facade), JQueryTyped (some tweaked methods over JQuery to make them work better in Scala), and JQueryExtensions(围绕 JQuery 构建的一些高级函数)中看到这种方法的实际应用。这些是使用 package.scala
中的隐式定义组合在一起的。就调用代码而言,所有这些看起来都像是 JQuery.
上的方法
我正在为 Atom.io https://github.com/ensime/ensime-atom 做这个 Ensime 包,我一直在考虑使用 scala.js 而不是编写 Coffeescript 的可能性。
Atom 是一个基于 Web 的编辑器,它使用 js 编写脚本并且基于 node.js。 plugin/package 通过指出具有一些特定的 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 模块,并且是一个 class 扩展了一个 class 并通过 require 获取。
太棒了。
我在想我会像我在 SO
import js.Dynamic.{global => g}
import js.DynamicImplicits._
private[views] object SpacePen {
private val spacePenViews = require("atom-space-pen-views")
val view = spacePenViews.view
}
但是如果我想输入 super-class,我可以做一个 facade-trait 然后做 asInstanceOf 吗?
其次,我想知道如何将 class 导出为节点模块。我发现了这个:
https://github.com/rockymadden/scala-node/blob/master/main/src/main/coffeescript/example.coffee
这是正确的方法吗?我需要做沙盒吗?我不能直接从全局导入 module
并写 module.exports = _some_scala_object_
吗?
我也想知道如何扩展现有的 js classes。和这里问的问题一样,但是我不太明白答案:
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。当然可以。
非常感谢任何指点!
我本身并不是 Node 的专家,但要回答你的第一个问题,是的——如果你有一个指向 JS 对象的指针,并且你知道它的类型的详细信息,你几乎总是可以定义外观特征和 asInstanceOf 以使用它。应该可以。
至于最后一点,您基本上无法在 Scala.js 中扩展 JS classes -- 它根本不起作用。我们大多数人解决这个问题的方法是通过定义隐式 classes 或使用隐式 def 来获得 外观 扩展而不实际这样做。
例如,给定 JS class Foo,我可以写
implicit class RichFoo(foo:Foo) {
def method1() = { ... }
}
这实际上是 around Foo 的包装器,但是调用代码可以简单地调用 foo.method1() 而不必担心那个细节。
您可以在 jquery-facade, particularly in the relationship between JQuery (the pure facade), JQueryTyped (some tweaked methods over JQuery to make them work better in Scala), and JQueryExtensions(围绕 JQuery 构建的一些高级函数)中看到这种方法的实际应用。这些是使用 package.scala
中的隐式定义组合在一起的。就调用代码而言,所有这些看起来都像是 JQuery.