Как динамически загрузить несколько оптимизированных модулей 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/ префикс).

Другие вопросы по тегам