#requirejs #js-amd #curljs
#requirejs #js-amd #curljs
Вопрос:
Мое понимание модулей 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:
Есть несколько причин, по которым вы можете захотеть использовать require()
в модуле.
Но сначала убедитесь, что вы запрашиваете ссылку на правильную require
переменную. В вашем примере ссылка на require
является глобальной. Вам нужна ссылка на a 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
:
- вы не знаете, какие модули необходимы во время сборки (или во время загрузки) из-за условий выполнения
- вы явно хотите отложить загрузку некоторых модулей до тех пор, пока они не понадобятся
- вы хотите загрузить вариант модуля на основе результатов обнаружения функций (хотя что-то вроде плагина dojo «has!» может быть лучшим решением (извините, ссылка ускользает от меня))
Наконец, AMD определяет второе использование require
для совместимости с модулями, созданными в CommonJS Modules / 1.1, которые затем упаковываются в a 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 , BDOAD и curl.js 0.6 ) обнаружит этот гибридный формат AMD / CJSM1.1 и найдет зависимости, сканируя модуль на require
наличие вызовов.
Комментарии:
1. лучшая ссылка, которую я могу найти для has.js : mail.dojotoolkit.org/pipermail/dojo-contributors/2011-January/… Это не объясняет плагин, просто упоминает его.
2. если у кого-нибудь достаточно очков для создания тега curljs, я был бы признателен! 🙂
3. Итак, если у меня есть модуль, которому требуется определенная функциональность, недоступная во всех браузерах, я могу определить модуль как обычный, а затем внутри я могу выполнить условную проверку, а затем потребовать () соответствующие модули, которые заполняют недостающую функциональность, верно? И я предполагаю, что во время «сборки» я все равно мог бы минимизировать этот модуль с помощью моего сценария сборки, поэтому я не асинхронно загружаю неминифицированный сценарий модуля.
4. Правильно, это цель has! плагин. Цель состоит в том, чтобы создать карту строк UA * для профилей функций. Ваш сервер может либо выбрать настраиваемый файл из списка предварительно скомпилированных, объединенных файлов для строки UA текущего браузера, либо создать его точно в срок (и, надеюсь, кэшировать его для последующего использования). * Следует отметить, что не все «на борту» с повторным введением UA sniffing!
5. Справедливо ли это для первой точки входа «require», указанной после блока require.config() ? Я установил для enforceDefine значение true, которое помещает блок конфигурации внутрь define() , затем точка входа вызывается с использованием глобального «require» сразу после конфигурации.