2011-10-20 6 views
18

mia comprensione di moduli AMD (utilizzando per esempio RequireJs o curl.js) è:Con i moduli AMD, quando (o perché) è OK utilizzare use() all'interno di define()?

require() viene utilizzata per caricare in modo asincrono moduli diversi e quando caricato quindi viene eseguita la richiamata fn.

e di definire un modulo, si avrebbe script separati che utilizzano define()

ma ho visto alcuni moduli usano require() all'interno della loro definizione di funzione, per esempio

define([a, b, c], function(i, ii, iii){ 
    require([d, e, f], function(d, e, f) { 
     // do some stuff with these require()'d dependancies 
    }) 
    /* rest of the code for this module */ 
}) 

ma trovo questa confusione perché avrei pensato che se un modulo ha dipendenze allora dovrebbero essere attraversato tramite la funzione principale define([dependancies], fnDefinition) e non all'interno di esso tramite require() come per l'esempio di cui sopra sta facendo.

C'è un ragionamento dietro questo?

risposta

27

Ci sono alcuni motivi per cui si potrebbe voler utilizzare require() in un modulo.

Prima di tutto, accertarsi di richiedere un riferimento alla variabile require corretta. Nel tuo esempio, il riferimento a require è un globale. Si desidera un riferimento a un require con ambito al contesto del modulo (talvolta chiamato "richiesta locale"). Questo è facile:

define(["a", "b", "c", "require"], function(i, ii, iii, require){ 
    require(["d", "e", "f"], function(moduleD, moduleE, moduleF) { 
     // do some stuff with these require()'d dependencies 
    }) 
    /* rest of the code for this module */ 
}); 

Il motivo principale questo è importante è quello di garantire che ids relativo modulo (ad esempio "./peerModule" o "../unclePath/cousinModule") vengono risolti correttamente. (Questo è uno dei motivi, curl.js non ha una globale require per impostazione predefinita.)


motivi per utilizzare un locale require:

  1. non si sa quali moduli sono necessario al momento della compilazione (o al momento del caricamento) a causa delle condizioni di run-time
  2. si desidera esplicitamente posticipare il caricamento di alcuni moduli finché non sono necessari
  3. si desidera caricare una variante di un modulo in base ai risultati di funzionalità rilevamento (anche se qualcosa del genere dojo di "ha!" plug-in potrebbe essere una soluzione migliore (scusate, link che mi sfugge))

Infine, AMD definisce un secondo utilizzo di require per la compatibilità con i moduli creati nel CommonJS Moduli/1.1 che vengono poi avvolti in a define. Si presenta così:

define(function(require, exports, module){ 
    var a = require("pkgZ/moduleA"), // dependency 
     b = require("pkgZ/moduleB"); // dependency 
    /* rest of the code for this module */ 
}); 

Gli sviluppatori di javascript sul lato server possono trovare interessante questo formato. :)

Alcuni caricatori AMD (come RequireJS 0.2+, dojo 1.7+, bdLoad e curl.js 0.6+) rileveranno questo formato ibrido AMD/CJSM1.1 e troveranno le dipendenze scansionando il modulo per le chiamate require.

+0

collegamento migliore che posso trovare per has.js: http://mail.dojotoolkit.org/pipermail/dojo-contributors/2011-January/023462.html Non spiega il plugin, lo menziona semplicemente. – unscriptable

+0

se qualcuno ha abbastanza punti per creare un tag curljs, lo apprezzerei! :) – unscriptable

+0

Quindi, se ho un modulo che ha bisogno di certe funzionalità che non sono disponibili in tutti i browser, posso definire il modulo come normale e poi dentro posso fare un controllo condizionale e poi richiedere() i moduli rilevanti che hanno il polyfill mancante funzionalità, giusto? E suppongo che in "tempo di compilazione" potrei ancora minimizzare quel modulo usando il mio script di build, quindi non è che sto caricando in modo asincrono uno script di modulo non minorato. – Integralist