Как динамически загрузить несколько оптимизированных модулей requirejs в производственной среде?
Я начал играть с require js на фиктивном проекте. Теперь я хочу использовать сценарий r.js для создания своего проекта для производства.
Контекст таков:
Основной файл с именем start.js:
require([/* some stuff */], function (){ /* app logic */ });
который имеет, если это решает, что мне нужно, основываясь на каком-то условии.
Требуемые файлы - это ModuleA или ModuleB
И ModuleA, и ModuleB имеют зависимости.
define([/*some deps*/], function(dep1, dep2...) { /* app logic */ return { /* interface */ }
Все отлично работает в режиме разработки, до оптимизации и объединения модулей.
При сборке с помощью r.js я указываю в качестве целей модуля следующее: modules: [ { name: "start" }, { name: "ModuleA" }, { name: "ModuleB" } ]
Проблема в том, что мой ModuleA становится:
define(dep1 ..);
define(dep2 ..);
define(ModuleA ..);
Но ничто не загружает от ModuleA. Код из ModeulA в разработке загружается и выполняется, код после сборки загружается, но не запускается.
Как я мог решить эту проблему?
ОБНОВИТЬ
http://pastebin.com/p1xUcY0A -> start.js
http://pastebin.com/dXa6PtpX -> Модуль A js-animation.js
http://pastebin.com/xcCvhLrT -> ModuleB css-animation.js нет ошибок.
http://pastebin.com/j51V5kMt -> Файл конфигурации r.js, используемый при запуске оптимизатора.
http://pastebin.com/UVkWjwe9 -> Как выглядит js-animation.js после запуска r.js. Это файл, который имеет проблемы. Я не получаю модуль js-animation из этого файла. Требование не возвращает мой объект js-animation.
Редактировать:
После удаления файла.js в конце определений модуля и в начале js оптимизированным файлом start.js является http://pastebin.com/LfaLkJaT а модулем js-animations - http://pastebin.com/qwnpkCC6. В chrome эта ошибка появляется в моей консоли http://pastebin.com/Hq7HGcmm
2 ответа
Кажется, это проблематично с текущей реализацией require.js. Обходным путем было создать глобальный модуль-посредник или модуль-посредник, чтобы все динамически загружаемые модули вызывали посредник и объявляли себя через событие. Это сработало для меня.
Я считаю, что проблема с вашей настройкой заключается в том, что вы заканчиваете имена зависимостей вашего модуля в .js
, Согласно документам:
RequireJS также предполагает, что по умолчанию все зависимости являются сценариями, поэтому он не ожидает увидеть конечный суффикс ".js" на идентификаторах модулей. RequireJS автоматически добавит его при переводе идентификатора модуля в путь.
Если RequireJS видит имя модуля, оканчивающееся на .js
это предполагает, что имя модуля является путем относительно документа. Завершая имена зависимостей вашего модуля в .js
он отлично работает в режиме разработки, потому что RequireJS пойдет и загрузит файл, указанный как зависимость. В вашем случае он загрузит файл js/js-animation.js
см аноним define
и загрузите модуль правильно.
В производстве ваш start.js
модуль по-прежнему требует "js/js-animation.js"
, RequireJS загрузит ваш оптимизированный модуль по пути js/js-animation.js
но теперь оптимизатор преобразовал ваши анонимные модули в именованные модули (в данном случае "js/js-animation"
). В результате файл будет загружен, но нет define
у модулей в файле есть имя, которое соответствует "js/js-animation.js"
так что в некотором смысле ваш модуль анимации отсутствует.
Решение / TL;DR: удалить трейлинг .js
от всех ваших имен зависимостей модулей (и ваших определений модулей в конфиге r.js), и вы должны быть в порядке. Так что ваши start.js
должен стать (изменения в строке 4):
require([], function () {
var $html = $("html"),
animationModule = localStorage['cssanimations'] == 'true' ?
'js/css-animation' : 'js/js-animation',
$doc = $html.find("body");
console.debug("loading ", animationModule);
require([animationModule], function( animationModule ) {
animationModule.run({
target : $("div.flex")
});
} );
} );
Также обратите внимание, что вы можете использовать baseUrl
а также paths
в вашей конфигурации RequireJS, чтобы очистить имена модулей (например, чтобы вы могли удалить js/
префикс).