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

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

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

Мое замешательство: зачем вообще нужен загрузчик? Если у вас нет очень необычных обстоятельств, которые заставляют вас делать 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() вызовы внутри этого запускают последующие асинхронные выборки кода?

5 ответов

Решение

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

** Но не могу найти это прямо сейчас.

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

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

Будьте осторожны с ограничениями, которые накладывает миндаль, чтобы работать

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