Con i moduli AMD, quando (o perché) va bene usare require () all'interno di define ()?
Domanda
La mia comprensione dei moduli AMD (utilizzando ad esempio RequireJs o curl.js) è:
require()
viene utilizzato per caricare in modo asincrono diversi moduli e quando viene caricato viene eseguito il callback fn.
E per definire un modulo, dovresti avere script separati che usano define()
Ma ho visto alcuni moduli utilizzare require()
all'interno della loro definizione di funzione, ad 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 lo trovo confuso perché avrei pensato che se un modulo ha dipendenze, allora dovrebbero essere passate attraverso la funzione principale define([dependancies], fnDefinition)
e non al suo interno tramite require()
come nell'esempio sopra.
C'è un ragionamento alla base di questo?
Soluzione
Ci sono alcuni motivi per cui potresti voler usare require()
in un modulo.
Ma prima assicurati di richiedere un riferimento alla variabile require
corretta. Nel tuo esempio, il riferimento a require
è un globale . Si desidera un riferimento a un require
che abbia come ambito il contesto del modulo (a volte 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 per cui questo è importante è assicurarsi che gli ID dei relativi moduli (ad esempio "./peerModule" o "../unclePath/cousinModule") siano risolti correttamente. (Questo è uno dei motivi, curl.js non ha un require
globale per impostazione predefinita.)
Motivi per utilizzare un require
locale:
- non sai quali moduli sono necessari in fase di compilazione (o in fase di caricamento) a causa delle condizioni di runtime
- desideri esplicitamente posticipare il caricamento di alcuni moduli finché non sono necessari
- si desidera caricare una variazione di un modulo in base ai risultati del rilevamento di funzionalità (sebbene qualcosa come il plug-in "has!" di dojo potrebbe essere una soluzione migliore (scusate, il collegamento mi sfugge))
Infine, AMD definisce un secondo utilizzo di require
per la compatibilità con i moduli creati in CommonJS Modules / 1.1 che vengono poi inseriti in un define
. Hanno questo aspetto:
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 lato server potrebbero trovare interessante questo formato. :)
Alcuni loader 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
.