【问题标题】:how to export variables from coffeescript in meteor packages如何从流星包中的咖啡脚本中导出变量
【发布时间】:2015-03-26 20:48:09
【问题描述】:

我对如何将导出的变量与咖啡脚本流星包一起使用感到困惑。

[编辑] 具体例子。 我遵循了各种建议,并有一个 JS 文件_defines.js

//defines.js
Ribot = {}

然后

# server.coffee

Meteor.startup ->
  Ribot = new Bot()

Meteor.methods botReply: (obj) ->
  reply = Ribot.reply("user", obj.text)

所以问题是启动块中的 Ribot 对象在流星方法块中不可用。

当我用 javascript 编写类似的代码时:

Meteor.startup( function() {
  Ribot = new Bot();

Meteor.methods({
  botReply: function(obj) {
    reply = Ribot.reply("user", obj.text)

一切正常。

目前要解决的问题是根据流星的咖啡脚本支持定义所有内容以挂起 share.Ribot

因此,对于第一步,我实际上不需要将 Ribot 对象导出到包之外,因为目前大部分接口都是通过 Meteor.methods 实现的,但我最终还是需要这样做。


详情如下

There are more complicated suggestions,但我发现包中的工作与正常的 CS 应用程序开发相反。

例如:

Rbot = {}   # no @ on declaration

Meteor.startup ->
  @RBot = new Thing()    # use @ in references
  console.log("new Rbot", @RBot)

然后在 package.js 中

api.export(['RBot']);

它现在可供应用使用。

但是,在我的应用程序(不是包)中正常使用咖啡脚本时,情况正好相反。例如

# use @ when declaring
@SceneData = new Meteor.Collection("SceneData")

Meteor.startup ->
  if Meteor.isServer
    Meteor.publish "SceneData", (query, fields) ->
      # dont use @ when referencing
      return SceneData.find(query, fields)

这似乎也与正常的咖啡脚本在流星之外的工作方式不同(见下文)。

在应用程序中,我认为这可能是因为流星正在调用具有与顶级窗口相同的“this”对象的方法?那么还有一层“魔法”在发生吗? 而在包 Meteor 中包含的闭包比咖啡脚本本身更多。

如果有人可以提出“正确”的做法,或者解释为什么在同一个框架中需要这两种相反的 wrapping/@ref 样式,那将很有启发性。

编译器示例:

@outer = "outer"
inner = "inner"

p1 = () ->
  console.log @outer   # wont run
  console.log(outer)

p2 = () ->
  console.log inner
  console.log @inner

p3 = () =>
  console.log @outer
  console.log(outer)


p1()
p2()
p3()

// compiles to:

(function() {
  var inner, p1, p2, p3;

  this.outer = "outer";

  inner = "inner";

  p1 = function() {
    console.log(this.outer);
    return console.log(outer);
  };

  p2 = function() {
    console.log(inner);
    return console.log(this.inner);
  };

  p3 = (function(_this) {
    return function() {
      console.log(_this.outer);
      return console.log(outer);
    };
  })(this);

  p1();

  p2();

  p3();

}).call(this);

【问题讨论】:

  • 包方法允许您导出变量而不将它们附加到全局对象。这意味着 Meteor 可以将变量暴露给依赖它的包,同时对其他包和/或应用程序代码隐藏它。这意味着包,无论是用 JS 还是 CS 编写的,都不会污染全局命名空间,除非它们直接被应用程序依赖。
  • api.export(['RBot']); 旨在使您的顶级包所需的导出可用于应用程序。但在许多情况下,它在导出时找不到要引用的已定义 RBot,因此它只是在应用程序的(全局)命名空间中提供 RBot = undefined。
  • 嗯,我有点困惑。导出时找不到已定义的变量是什么意思?正如您在文章开头所说,您需要api.export 行,并且需要在代码中声明变量。但是api.export 不会自动将变量公开给应用程序的全局范围。考虑一个依赖包 A 的应用程序,它依赖于包 B。应用程序代码将只能看到包 A 的导出,这些导出将附加到全局对象。它看不到包 B 的导出,因为它只是间接依赖它。

标签: javascript meteor coffeescript


【解决方案1】:

如果您在包中写入@myVariable = value,则无需导出myVariable,因为没有名为myVariable包变量,因为您已将其附加为新属性到全局对象。但是,您应该避免这样做,因为包不应该修改全局对象,而是导出它的一些包变量。

但是,包变量必须定义为全局变量(在 JavaScript 中:myVariable = value(和 不是 var myVariable = value),缺点是在 CoffeeScript 中没有等效的语句(在 CoffeeScript @ 987654327@ 编译为var myVariable = value,它创建了一个文件作用域变量)。为了解决这个问题,meteor 引入了shared 变量(包含一个对象),想法是包作用域变量应该作为属性分配给这个对象。在the docs for CoffeeScript in Meteor 中了解更多信息。

【讨论】:

    猜你喜欢
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-05
    • 1970-01-01
    • 1970-01-01
    • 2017-10-18
    相关资源
    最近更新 更多