2012-12-14 19 views
19

Ho visto persone utilizzare una "sintassi" di definizione alternativa in require js rispetto a quanto descritto nella documentazione di require js, o in molti tutorial.Perché utilizzare alternate requirejs define: define (function (require) {...}

Il solito definire "sintassi":

define(['module/first'], function (firstModule) { 
    //Module code with a dependency on module/first goes here. 
}); 

Il alternate definire "sintassi":

<script data-main="app/config" src="assets/js/libs/require.js"></script> 

file: config.js:

require.config({ 
    paths: { 
     jquery:  '../assets/js/libs/jquery' 
    } 
}); 
require(['app']); 

file: app.js:

define(function(require) { 
    var FirstModule = require('modules/first'); 
    //Module code with a dependency on module/first goes here. 

Quali sono i vantaggi e gli svantaggi di usare questa alternativa "sintassi"?

risposta

40

Penso che la tua spiegazione sia un po 'fuorviante: in entrambi i casi, si avrà una chiamata di livello superiore require con un attributo data-main che specifica un file per avviare il processo di richiesta di moduli diversi.

così tipicamente si avrà questo nel tuo HTML:

<script data-main="app/config" src="assets/js/libs/require.js"></script> 

Poi, in entrambi i casi, si dovrebbe avere un file app/config che definisce la configurazione (anche se si potrebbe farlo direttamente nel codice HTML) e chiede soprattutto require sui vostri moduli:

require.config({ 
    paths: { 
    jquery:  '../assets/js/libs/jquery' 
    } 
}); 
require(['app']); 

Ora, è quando si arriva a definire i moduli con dipendenze che questi stili diversi. Nello stile amd si passa i nomi di modulo (percorsi) come una matrice, e una funzione che prende lo stesso numero di argomenti:

app.js

define(['module/first', 'module/second', 'module/third'], function (firstModule, secondModule, thirdModule) { 
    // use firstModule, secondModule, thirdModule here 
}); 

nella sintassi CommonJS semplificato, basta passare require in define e quindi richiedono qualunque moduli è necessario in linea:

app.js

define(function(require) { 
    var firstModule = require('modules/first'); 
    var secondModule = require('modules/second'); 
    var thirdModule = require('modules/third'); 
    // use firstModule, secondModule, thirdModule here 

} 

Tornando alla tua domanda iniziale, i vantaggi dello stile CommonJS rispetto allo stile amd dovrebbero essere chiari.

Per una cosa, con la sintassi convenzionale, se sono richiesti molti moduli, è molto assegnare facilmente i moduli ai nomi di variabile errati. Considerate questo caso comune:

define(['jquery', 'underscore', 'backbone', 'modules/first', 'modules/second', 'modules/third', 'i18n', 'someOtherModule'], function ($, _, Backbone, first, second, third, I18n, someOtherModule) { 
    // ... 
}); 

Subito, si può vedere che quando aggiungiamo un nuovo modulo a questa lista, dobbiamo essere molto attenti che il nuovo argomento di funzione corrispondente appare nel posto giusto, altrimenti ci può avere jQuery assegnato a Backbone, ecc. In alcuni casi questo può creare bug molto sottili che sono difficili da rintracciare.

Ora considerano la sintassi CommonJS:

define(function(require) { 
    var $ = require('jquery'); 
    var _ = require('underscore'); 
    var Backbone = require('backbone'); 
    var firstModule = require('modules/first'); 
    var secondModule = require('modules/second'); 
    var thirdModule = require('modules/third'); 
    var I18n = require('i18n'); 
    var someOtherModule = require('someOtherModule'); 
    // ... 
} 

Nota che:

  1. L'abbinamento del modulo a nome della variabile è molto chiara.
  2. L'ordine delle istruzioni require non è importante, poiché i nomi delle variabili vengono abbinati separatamente anziché come associazione tra una matrice e una funzione.
  3. I moduli non devono essere assegnati prima. Possono essere assegnati ovunque, purché prima che il modulo venga effettivamente utilizzato.

Questi sono solo alcuni dei motivi che mi vengono in mente, sono sicuro che ce ne sono altri. Fondamentalmente, se hai solo una o due dipendenze, la sintassi andrà bene. Ma se si ha una rete complessa di dipendenze dei moduli, la sintassi CommonJS è probabilmente preferibile.

Si noti che nei documenti RequireJS, accennano this small caveat:

Non tutti i browser danno un Function.prototype.toString utilizzabile) risultati (. A partire da ottobre 2011, i browser PS3 e Opera Mobile meno recenti non lo fanno. È più probabile che quei browser necessitino di una build ottimizzata dei moduli per i limiti di rete/dispositivo, quindi basta fare una build con un ottimizzatore che sappia come convertire questi file nel formato dell'array di dipendenza normalizzato, come l'ottimizzatore RequireJS.

Ma questo non è un grosso problema:

Dal momento che il numero di browser che non possono supportare questa toString() di scansione è molto piccolo, è sicuro da usare questa forma zuccherate per tutti i moduli, in particolare se ti piace allineare i nomi delle dipendenze con le variabili che manterranno i loro valori del modulo.

+0

Sono d'accordo con i vantaggi dello stile comune. Hai qualche idea o idea sul perché lo stile di AMD sia preferito nelle esercitazioni e nei documenti di requirejs? Se il risultato è lo stesso, perché non consigliamo a tutti di utilizzare lo stile commonjs? È l'unica ragione del "piccolo avvertimento"? – joholo

+1

Non posso davvero dire, ma suppongo che sia per lo più storico: il formato amd è lo standard, mentre il CommonJS semplificato è uno strato di "zucchero" in più. Se insegni a RequireJS, allora ha senso seguire il formato che ha una storia più lunga e un'adozione più ampia, anche se la versione "zuccherata" è più semplice e discutibilmente migliore. Intendiamoci qui, per lo più, sto solo ipotizzando qui. –

+1

Si potrebbe anche sostenere, suppongo, che obbligandoti a definire tutte le tue dipendenze nella parte superiore di un modulo (prima di ogni altra cosa), il formato amd rende queste dipendenze più facili da trovare a colpo d'occhio. Anche se si usa il formato CommonJS e si punta a mettere le dipendenze nella parte superiore del modulo, questo non è davvero un problema. –