Зачем нужны объединенные модули RequireJS AMD для загрузки?

Мы любим RequireJS и AMD во время разработки, где мы можем редактировать модуль, удалять перезагрузку в нашем браузере и сразу видеть результат. Но когда пришло время объединить наши модули в один файл для развертывания производства, по-видимому, должен присутствовать еще один загрузчик AMD, независимо от того, является ли этот загрузчик самим RequireJS или его меньшим партнером "миндалем", как описано здесь:

http://requirejs.org/docs/faq-optimization.html#wrap

Моя путаница: зачем вообще нужен загрузчик? Если у вас нет необычных обстоятельств, из-за которых вам нужно делать вызовы require() внутри ваших модулей, похоже, что ряд модулей AMD может быть объединен без присутствия загрузчика вообще. Простейшим возможным примером может быть пара модулей, таких как:

ModA.js:

define([], function() {
    return {a: 1};
});

ModB.js:

define(['ModA'], function(A) {
    return {b : 2};
});

Учитывая эти два модуля, кажется, что конкатенатор может просто создать следующий текст и не нагружать производственный сервер или браузер дополнительной полосой пропускания или вычислениями, требуемыми либо RequireJS, либо Almond.

Я представляю себе конкатенатор, который производит (и я использую шеврон-кавычки ",", чтобы показать, где были вставлены фрагменты из двух модулей выше):

(function() {
    var ModA = «function() {
        return {a: 1};
    }»();
    var ModB = «function(A) {
        return {b : 2};
    }»(ModA);
    return ModB;
})();

Это, насколько я вижу, правильно воспроизведет семантику AMD с минимальным посторонним клеем JavaScript. Есть ли такой конкатенатор? Если бы не я, я был бы дураком, думая, что я должен написать один - есть ли действительно очень мало базовых кодов, которые состоят из простых и чистых модулей, написанных с помощью define(), и которые больше не нуждаются в дальнейших вызовах require() внутри, которые начинаются позже асинхронными выборки кода?

Ответ 1

Оптимизатор AMD имеет возможность оптимизировать больше, чем количество загружаемых файлов, он также может оптимизировать количество модулей, загруженных в память.

Например, если у вас есть 10 модулей и вы можете оптимизировать их до 1 файла, вы сохранили себе 9 загрузок.

Если страница использует все 10 модулей, то это здорово. Но что, если Page2 использует только 1? Загрузчик AMD может задержать выполнение функции factory до тех пор, пока модуль не будет require 'd. Следовательно, Page2 запускает только одну функцию factory ".

Если каждый модуль потребляет 100 килобайт памяти при require 'd, тогда инфраструктура AMD, которая имеет оптимизацию времени выполнения, также сохранит нам 900 КБ памяти на странице.

Примером этого может быть диалоговое окно "О коробке". Там, где его выполнение задерживается до самой последней секунды, поскольку в 99% случаев он не будет доступен. Например. (в свободном синтаксисе jQuery):

aboutBoxBtn.click(function () {
    require(['aboutBox'], function (aboutBox) {
        aboutBox.show();
    }
});

Вы сохраняете расходы на создание объектов JS и DOM, связанных с "О блоке", пока не убедитесь, что это необходимо.

Для получения дополнительной информации см. Задержка выполнения определяет, пока сначала не потребуется, чтобы requirejs взяли на себя это.

Ответ 2

Единственное реальное преимущество заключается в том, что вы используете модули по разделам, чтобы обеспечить независимость кеширования.

Ответ 3

У меня была такая же потребность, поэтому я создал простой компилятор AMD для этой цели, который делает именно это. Вы можете получить его на https://github.com/amitayh/amd-compiler

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

Ответ 4

Если вы скомпилируете код с require.js в один большой файл для производства, вы можете использовать almond.js, чтобы полностью заменить требуемый,

Алмонд обрабатывает только управление ссылками модулей, а не загрузку, которая больше не нужна.

Будьте осторожны с restrictions миндалем, чтобы работать

Ответ 5

Нет причин, по которым не может быть инструмента сборки, такого как тот, который вы предлагаете.

В последний раз * я посмотрел на вывод оптимизатора, он преобразовал модули в явно именованные модули, а затем объединил их вместе. Он полагался на себя, чтобы убедиться, что функции factory были вызваны в правильном порядке и что соответствующие объекты модуля были переданы. Чтобы создать такой инструмент, как вы хотите, вам придется явно линеаризовать модули - не невозможно, а намного больше работать. Вероятно, поэтому это не было сделано.

Я считаю, что у оптимизатора есть функция автоматического включения, требующая самого себя (или миндаля) во встроенный файл, так что вам нужно только одну загрузку. Это будет больше, чем выход инструмента сборки, который вы хотите, но в остальном то же самое.

Если появился инструмент сборки, который создавал тип вывода, который вы запрашиваете, в случае синхронного require было бы более осторожным использование exports вместо возврата, и любое другие возможности совместимости CommonJS.

* Это было несколько лет назад. 2010, я думаю.

** Но, похоже, он не может найти его прямо сейчас.