2012-02-15 72 views
32

当我创建一个新的coffeescript文件时,我无法从另一个文件中访问编译代码中的代码,因为它被封装在某个函数作用域中。例如:与coffeescript的多个文件通信

的CoffeeScript:

class ChatService 
    constructor: (@io) -> 

生成的JavaScript:

(function() { 
    var ChatService;  
    ChatService = (function() {  
    function ChatService(io) { 
     this.io = io; 
    }  
    return ChatService;  
    })();  
}).call(this); 

当试图调用ChatService在另一个文件中,它没有定义。如何用coffeescript处理多个文件?

+0

如果您使用Rails,则必须确保在尝试引用它之前调用任何相关的coffeescript文件*。一旦在需要其他文件的文件中设置了“require”指令,您就可以访问变量等。 – 2015-08-09 13:40:10

回答

56

取决于这是客户端还是服务器端代码,有两种稍微不同的方法。

客户端:在这里,我们重视的事情,应该可以跨文件的全局命名空间(window)如下:

class window.ChatService 
    constructor: (@io) -> 

然后,在另一个文件中同时ChatServicewindow.ChatService将允许访问类。


服务器端:在这里,我们必须用exportsrequire。在ChatService.coffee文件,你将有以下:

class exports.ChatService 
    constructor: (@io) -> 

然后,它从另一个文件,让你可以使用:

ChatService = require('ChatService.coffee').ChatService 

注:如果您是从越来越多班ChatService.coffee,这是一个地方的CoffeeScript的字典拆包真正的亮点,如:

{ChatService, OtherService} = require('ChatService.coffee') 

Both:基本上,我们根据所处的环境选择是运行服务器端还是客户端代码。一种常见的方式来做到这一点:

class ChatService 
    constructor: (@io) -> 

if typeof module != "undefined" && module.exports 
    #On a server 
    exports.ChatService = ChatService 
else 
    #On a client 
    window.ChatService = ChatService 

为了得到它:

if typeof module != "undefined" && module.exports 
    #On a server 
    ChatService = require("ChatService.coffee").ChatService 
else 
    #On a client 
    ChatService = window.ChatService 

第二块的else子句可以跳过,因为ChatService已经是指连接到window参考。

如果你打算在这个文件中定义了大量的类,它可以更容易地定义它们,如:

self = {} 

class self.ChatService 

再附上他们像module.exports = self在服务器上,_.extend(window, self)在客户端(根据需要替换_.extend与另一个extend函数)。

+1

对于事物的node.js端+1。 – 2012-02-15 17:09:28

+2

感谢您提供node.js和客户端方法,我都需要。 – 2012-02-15 20:35:55

+0

就像“mu太短”的答案一样,您也可以执行exports.App.ClassName。我想你可以称之为“命名空间”的应用程序部分。如果我错了,请纠正我。 – Chris 2012-10-10 00:13:15

23

通常的做法是在window定义一个全局命名空间:

window.App = { } 

这将去的地方在你的应用程序的初始化代码之前,任何其他事情发生。然后,为您的类:

class App.ChatService 
    constructor: (@io) -> 

这允许您通过App任何你想引用你的类,你不担心污染全局命名空间:

chatter = new App.ChatService 

如果你想为了让你的ChatService真正的全球,那么你可以使用class window.ChatService,但我建议反对,除了在最琐碎的应用程序。

AFAIK,node.js与window类似,但我对node.js不太了解,告诉你它是什么。

+1

在node.js中,通过将符号附加到'exports'来导出符号。在一个模块中:exports.ChatService = ChatService;在另一个中:ChatService = require(“./ chat”)。ChatService。 – 2012-02-15 12:19:13

+0

@Linus:谢谢,我认为Aaron Dufour在我接触之前就已经说过了。 – 2012-02-15 17:11:19

0

用命名空间分隔你的类,并使用cake将它们全部编译成一个(或多个)生成的.js文件。 Cakefile被用作控制咖啡脚本编译顺序的配置 - 对于更大的项目非常方便。

蛋糕是很容易的安装和设置,从VIM调用蛋糕,而你正在编辑您的项目是那么简单

:!cake build 

,您可以刷新浏览器,看到的结果。

由于我也忙于学习构建文件和结合骨干和蛋糕使用coffeescript的最佳方式,因此我创建了一个small project on github以保留它作为我自己的参考,也许它也会帮助您蛋糕和一些基本的东西。所有已编译的文件都在www文件夹中,以便您可以在浏览器中打开它们,并且所有源文件(除蛋糕配置外)都在src文件夹中。在这个例子中,所有的.coffee文件被编译并合并在一个输出.js文件中,然后将其包含在html中。