С модулями AMD, когда (или почему) нормально использовать require () в define ()? - PullRequest
19 голосов
/ 20 октября 2011

Мое понимание модулей AMD (используя, например, RequireJs или curl.js) таково:

require() используется для асинхронной загрузки различных модулей, и при загрузке выполняется обратный вызов fn.

И чтобы определить модуль, у вас должны быть отдельные сценарии, которые используют define()

Но я видел, что некоторые модули используют require() внутри определения своей функции, например,

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 */ 
}) 

Но я нахожу это сбивающим с толку, потому что я подумал бы, что если у модуля есть зависимости, то они должны проходить через основную функцию define([dependancies], fnDefinition), а не внутри нее через require(), как это делает приведенный выше пример.

Есть ли причина этого?

1 Ответ

28 голосов
/ 20 октября 2011

Есть несколько причин, по которым вы можете захотеть использовать require() в модуле.

Но сначала убедитесь, что вы запрашиваете ссылку на правильную переменную require. В вашем примере ссылка на require является global . Вы хотите ссылку на require, которая ограничена контекстом вашего модуля (иногда называемого «локальным требованием»). Это легко:

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 */ 
}); 

Основная причина, по которой это важно, - убедиться, что относительные идентификаторы модулей (например, "./peerModule" или "../unclePath/cousinModule") разрешены правильно. (Это одна из причин, по умолчанию curl.js не имеет глобального require.)


Причины использования местного require:

  1. вы не знаете, какие модули необходимы во время сборки (или во время загрузки) из-за условий выполнения
  2. вы явно хотите отложить загрузку некоторых модулей до тех пор, пока они не понадобятся
  3. вы хотите загрузить вариант модуля на основе результатов обнаружения функций (хотя что-то вроде плагина dojo "has!" Может быть лучшим решением (извините, ссылка ускользает от меня))

Наконец, AMD определяет второе использование require для совместимости с модулями, созданными в CommonJS Modules / 1.1, которые затем обертываются в define. Это выглядит так:

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

Разработчики javascript на стороне сервера могут посчитать этот формат привлекательным. :)

Некоторые загрузчики AMD (такие как RequireJS 0.2+, dojo 1.7+, bdLoad и curl.js 0.6+) обнаруживают этот гибридный формат AMD / CJSM1.1 и находят зависимости путем сканирования модуля на наличие вызовов require.

...