2012-02-15 19 views
32

Quando creo un nuovo file coffeescript, non riesco ad accedere al codice nel codice compilato da un altro file perché viene incluso in alcune funzioni. Per esempio:Comunicazione di file multipli con coffeescript

CoffeeScript:

class ChatService 
    constructor: (@io) -> 

Generated Javascript:

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

Quando si cerca di chiamare ChatService in un altro file, non è definito. Come gestisco più file con coffeescript?

+0

Se si utilizza Rails, è necessario assicurarsi che qualsiasi file coffeescript dipendente sia chiamato * prima * si tenta di fare riferimento a esso. Una volta impostate le direttive "require" nei file che effettivamente hanno bisogno degli altri, otterrete l'accesso alle variabili, ecc. –

risposta

56

A seconda che si tratti di codice client o lato server, esistono due approcci leggermente diversi.

lato client: Qui abbiamo allegare cose che dovrebbero essere disponibili attraverso i file al namespace globale (window) come segue:

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

Poi, in un altro file sia ChatService e window.ChatService consentirà l'accesso alla classe .


lato server: Qui dobbiamo usare exports e require. Nel file ChatService.coffee, si avrebbe la seguente:

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

Quindi, per ottenere la cosa da un altro file è possibile utilizzare:

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

Nota: Se ci sono più classi che si stanno ottenendo da ChatService.coffee, questo è un posto dove dict di CoffeeScript disimballaggio brilla davvero, come ad esempio:

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

Entrambi: Fondamentalmente, scegliamo se eseguire il codice lato server o lato client in base all'ambiente in cui ci troviamo.Un modo comune per farlo:

class ChatService 
    constructor: (@io) -> 

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

per farlo:

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

La clausola else del secondo blocco possono essere saltati, poiché ChatService riferisce già al riferimento attaccato window.

Se avete intenzione di definire un sacco di classi in questo file, potrebbe essere più facile definirli come:

self = {} 

class self.ChatService 

E poi attaccarle come module.exports = self sul server e sul client _.extend(window, self) (sostituire _.extend con un'altra funzione extend appropriata).

+1

+1 per il lato node.js delle cose. –

+2

Grazie per aver fornito sia node.js sia l'approccio lato client, avevo bisogno di entrambi. –

+0

Come la risposta di "mu è troppo breve", potresti essere in grado di fare anche un export.App.ClassName. Immagino che potresti chiamare la parte App di quello "spazio dei nomi". Per favore correggimi se sbaglio. – Chris

23

L'approccio comune è quello di definire un namespace globale in window:

window.App = { } 

che sarebbe andato da qualche parte nel codice di inizializzazione dell'applicazione prima che accada qualcosa d'altro. E poi, per la classe:

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

che ti permette di fare riferimento la classe attraverso App ovunque si desidera e che non devono preoccuparsi di inquinare il namespace globale:

chatter = new App.ChatService 

Se si voleva per rendere il tuo ChatService veramente globale allora potresti usare class window.ChatService ma ti consiglio di farlo, tranne che nelle applicazioni più banali.

AFAIK, node.js ha qualcosa di simile a window ma non sono abbastanza familiare con node.js per dirti di cosa si tratta.

+1

In node.js, esportate i simboli allegandoli a 'exports'. In un modulo: exports.ChatService = ChatService; Nell'altro: ChatService = require ("./ chat"). ChatService. –

+0

@Linus: Grazie, penso che Aaron Dufour l'abbia coperto prima che ci arrivassi. –

0

Separa le tue classi con spazi dei nomi e utilizza cake per compilarle tutte in uno (o più) file .js risultanti. Cakefile viene usato come configurazione che controlla in quale ordine vengono compilati gli script del caffè - abbastanza utile con progetti più grandi.

torta è abbastanza facile da installare e configurare, invocando la torta da vim mentre si sta modificando il progetto è poi semplicemente

:!cake build 

e si può aggiornare il vostro browser e vedere i risultati.

Come sono anche impegnato a imparare il modo migliore di strutturare i file e utilizzare coffeescript in combinazione con backbone e cake, ho creato uno small project on github per tenerlo come riferimento per me stesso, forse ti aiuterà anche in giro torta e alcune cose di base. Tutti i file compilati sono nella cartella www in modo che sia possibile aprirli nel browser e tutti i file di origine (ad eccezione della configurazione della torta) si trovano nella cartella src. In questo esempio, tutti i file .coffee sono compilati e combinati in un file .js di output che viene quindi incluso in html.