2012-03-15 12 views
12

Sto cercando di capire il modello namespacing in clojurescript. Capisco che javascript non sia integrato con il supporto dello spazio dei nomi, quindi è stato un add on tramite la libreria di chiusura di google. Tuttavia, non capisco come il clojurescript si occupi di queste differenze. Qualcuno può spiegare per favore?Quali sono i trucchi del namespace per il clojurescript quando provengono dal clojure?

Diciamo per esempio che voglio usare le API di google charts e quando possibile vorrei usare la compilazione avanzata. Cosa utilizzo nella chiamata closure/build, come appare il modulo ns e qual è il modo migliore per fare riferimento all'api dal codice? Ho visto https://github.com/sritchie/contour ma quell'esempio non utilizza la compilazione avanzata e non vedo le opzioni che si riferiscono a google api nel file project.clj.

risposta

12

La dichiarazione dello spazio dei nomi è la stessa indipendentemente dal fatto che si utilizzi la compilazione in modalità semplice o avanzata. La differenza è che le librerie che non partecipano alla gestione delle dipendenze di google tramite goog.require('') e goog.provide('') devono essere referenziate esplicitamente tramite un file externs.js. Questo file, che si passa al compilatore cljs, fornisce gli stub di tutti i vars e dei metodi associati. Un tipico externs.js sarebbe qualcosa di simile:

// contents of externs.js 
var externalLibrary = {} 
var externalLibrary.method = function() {} 

Quindi, per fare riferimento a una chiusura libreria conoscenza google vostra dichiarazione dello spazio dei nomi è simile al seguente:

(ns my.namespace 
    (:require [goog.events.KeyCodes :as key-codes]) 

E che emette il seguente javascript:

goog.provide("my.namespace"); 
goog.require("goog.events.keycodes"); 

Nota che se vuoi chiamare il tuo closurescript da un altro file javascript devi taggare il metodo come esportato in modo che il compilatore di ottimizzazione sappia s per preservare il nome. (Ad esempio, si potrebbe avere un tag script in una pagina da cui si desidera chiamare una funzione javascript che è stato generato da ClojureScript)

che assomiglia a questo:

(defn ^:export externallyCalled []) 

L'altra cosa da tenere presente è che devi trattare in modo diverso le macro in clojurescript, questo perché la capacità di processarle "al volo" nel lettore non è presente nello stesso modo in cui è in clojure.

lo fai nel modo seguente (si noti che si sono tenuti a legare le macro con: come in questo caso)

(ns my.namespace 
    (:require-macros [my.macros :as my])) 

Se si chiama il codice che non ha partecipato alla gestione delle dipendenze di Google si accede tramite il js spazio dei nomi e l'interoperabilità javascript ...

(. js/nonGoogle (method args)) ; a method access 

(. js/nonGoogle -p) ; a property access 

tutti i soliti. anche le varianti funzionano ..

+0

è il: come opzione supportata per: utilizzare? dovrebbe anche esserci un vettore nell'esempio: requre-macros? Inoltre, potresti fare un esempio con google maps o charts? – bmillare

+0

@bmillare entrambe le catture. Ho risolto la risposta. Grazie (molto ritardato) – sw1nn

Problemi correlati