2012-06-07 13 views
9

So che questa domanda si presenta spesso in modo simile, ma nessuna soluzione sembra adattarsi perfettamente alle mie esigenze. Ho il seguente problema:Il modo migliore per concatenare i file JavaScript con le dipendenze e visualizzarli come modulo?

In fase di sviluppo uso più file JS (un singolo file ogni "oggetto"). Questi file JS hanno diverse dipendenze l'uno dentro l'altro - alcuni si affidano ad altri e ho bisogno di caricarli prima. Attualmente utilizzo RequireJS per caricare ogni file JS nell'ordine corretto, quindi definisco un modulo per ogni file. Bene e dandy. Ma ora voglio concatenare tutti i miei file JS in un unico file JS che dovrebbe essere un modulo stesso. Io uso il RequireJS optimizer r.js per farlo. Il mio problema: Ogni file JS è concatenato a un grande file JS, ma la definizione del modulo per ogni oggetto è inclusa. Non ho un grande modulo in un grande file, ma molti moduli in un unico grande file.

Successivamente ho provato il grunt per concatenare che funziona bene, ma ignora le dipendenze dei file. Semplicemente concatena ogni file in ordine alfabetico o devo codificare l'ordine nel mio gruntfile.

Come posso risolvere questo?

Proprio come un'illustrazione per il mio problema: Ho seguito i file (pseudo codice):

FileA 
- define FileA module 
- depends on FileB 
- FileA Logic 

FileB 
- define FileB module 
- FileB Logic 

E voglio questo output:

LibFile 
- define LibFile module 
- FileB Logic, FileA Logic 

ma ottengo questo con r.js (la definizione del modulo da FileA e FileB è copiata):

LibFile 
- define FileB module 
- FileB Logic 
- define FileA module 
- depends on FileB 
- FileA Logic 

E ottengo questo w esimo grugnito (nell'ordine sbagliato):

LibFile 
- FileA Logic 
- FileB Logic 

Forse che le domande è un po 'stupido, ma non riesco proprio a risolvere questo con gli strumenti tutti sembrano usare ... ho provato il plugin grugnito-requirejs, pure. Ma getta parecchi errori che non ho potuto risolvere.

Grazie, Pipo

+0

Perché averli tutti in un unico file è un problema ? Puoi usare quel file come modulo se hai usato il paradigma "pacchetto" per registrare i piccoli ... – ZenMaster

+0

Ciao ZenMaster, cosa intendi con paradigma "pacchetto"? Ho usato "define ([" ./ fileB "], function (fileB) {// codice per fileA; return fileA;});" per definire i miei moduli. Ma se ho molti piccoli moduli come questo su un grosso file e provo a caricare il file come questo "define ([" ./ LibFile "], function (LibFile) {// some code;});" LibFile non è definito. Non posso richiedere il file grande come un modulo. – Pipo

+0

Vedere la risposta. Spero possa aiutare. – ZenMaster

risposta

7

ho intenzione di spostarlo in una risposta. Solo così il codice è un po 'più chiaro.

Sto facendo questi per memoria (dato che non posso testarlo proprio ora) così alcune piccole cose potrebbero non essere del tutto accurate.

Dipende ovviamente da come si comprime i moduli, ma un modo è quello di registrare tutti i moduli più piccoli in un modulo più grande:

File A.js

define([], function() { 
    // do something 
    return A; 
}); 

File B.js

define(['path/to/A'], function(A){ 
    // do something with A and more 
    return B; 
}); 

Poi, li comprime insieme:

mylib File.js

define(['path/to/A', 'path/to/B'], function(A, B){ 
    return { 
     A : A, 
     B : B 
    } 
} 

È quindi possibile puntare il profilo build mylib.js e verranno combinati in un unico grande file . Non sarà un modulo completamente incapsulante, ma avrà un modulo di entrata che fa riferimento a tutto il resto. È quindi possibile utilizzare in questo modo:

require.config({ 
    paths : { 
     'path/to/mylib' : 'real/path/to/mylib/on/server' 
    } 
}); 
require(['path/to/mylib'], function(Lib) { 
    // do something using Lib.A or Lib.B 
} 

l'unica cosa a prestare attenzione è l'ID del file di grande modulo. Di default RequireJS build fornisce l'ID che corrisponde al percorso fisico (da appDir IIRC) e si deve corrispondere a quando si carica la dipendenza. In poche parole, se il file mylib.js risultante ha ricevuto il nome 'path/to/mylib', devi corrispondere a e caricarlo con lo stesso ID (utilizzando require.config.paths) o giocare con le mappe e simili (alcune delle quali richiedono RequireJS 2.0).

Quello che segue è il motivo che ho chiesto perché si vuole fare la cosa "grande modulo"

Altra cosa da notare è che tutti i moduli più piccoli interni ricevono anche gli ID corrispondenti a loro percorso fisico e è possibile utilizzare questi ID quando si utilizza il modulo di grande pacchetto (in modo che sia possibile accedere non solo attraverso Lib.A) se mylib.js è stato caricato:

require(['path/to/A'], function(A) { 
    // do something using A 
} 
+0

Ciao ZenMaster, non ho notato, che i moduli ottengono un ID predefinito che corrisponde al percorso fisico. Ora posso caricare e utilizzare il mio file concatenato. Grazie. – Pipo

Problemi correlati