Вам интересно, как
Module_Name/js/path/to/module
становится
//magento.example.com/static/frontend/Package/Theme/locale/Module_Name/js/path/to/module.js
Прежде всего, важно понимать, что для этого нужен только JS, а не какой-то особый соус Magento (хотя в других местах он есть). По большей части интерфейс использует только нормальное поведение RequireJS. Магия обычно заключается в том, как она генерируется pub/static, а именно в том, как view/area/web/js/path/to/module.jsона связана с символом pub/static/area/Package/theme/Module_Name/js/path/to/module.js. Это обрабатывается процессом статической компиляции Magento, и я не буду вдаваться в подробности.
requirejs-config.js
Введем новый файл, который Вы упоминаете: requirejs-config.js. Это какой-то особенный соус Magento 2, но, вероятно, не так много, как вы думаете.
Этот файл может быть любым JavaScript, но должен как минимум объявить (глобальную) переменную с именем config. configПривязанный объект передается напрямую в requireJS для его настройки.
Как это работает, Magento находит все requirejs-config.jsв проекте. Они могут быть в модуле view/area, в теме или в теме, в ее корневом каталоге и в переопределении модуля темы, например Magento_Catalog/requirejs-config.js. Обратите внимание, что это не включает ни одного дочернего элемента webкаталога. Этот файл, как правило, должен быть родственным webкаталогу.
После смещения каждого файла оформляется в замыкание (так что наша глобальная переменная фактически не существует), и строка в конце замыкания передает configпеременную requireобъекту. Это можно увидеть:
Это Magento_Checkout::view/frontend/requirejs-config.js:
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
var config = {
map: {
'*': {
discountCode: 'Magento_Checkout/js/discount-codes',
shoppingCart: 'Magento_Checkout/js/shopping-cart',
regionUpdater: 'Magento_Checkout/js/region-updater',
opcOrderReview: 'Magento_Checkout/js/opc-order-review',
sidebar: 'Magento_Checkout/js/sidebar',
payment: 'Magento_Checkout/js/payment',
paymentAuthentication: 'Magento_Checkout/js/payment-authentication'
}
}
};
Когда он доберется до внешнего интерфейса, он будет выглядеть так:
(function() {
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
var config = {
map: {
'*': {
discountCode: 'Magento_Checkout/js/discount-codes',
shoppingCart: 'Magento_Checkout/js/shopping-cart',
regionUpdater: 'Magento_Checkout/js/region-updater',
opcOrderReview: 'Magento_Checkout/js/opc-order-review',
sidebar: 'Magento_Checkout/js/sidebar',
payment: 'Magento_Checkout/js/payment',
paymentAuthentication: 'Magento_Checkout/js/payment-authentication'
}
}
};
require.config(config);
})();
Это украшение можно увидеть в Magento\Framework\RequireJs\Config.
Каждый из этих украшенных файлов объединяется и сбрасывается static/_requirejs/area/Package/theme/locale/secure/requirejs-config.js. Это местоположение заранее согласовано, так что HTML загружает этот скрипт, так как он требует requireJS:
<script type="text/javascript" src="https://magento.example.com/static/area/Package/theme/locale/requirejs/require.js"></script>
<script type="text/javascript" src="https://magento.example.com/static/_requirejs/area/Package/theme/locale/secure/requirejs-config.js"></script>
Я рассматриваю, как настроить RequireJS за рамками этого ответа, но у них есть довольно хорошая документация по этому вопросу . Однако следует отметить две важные вещи:
- Последовательные вызовы
require.configбудут накладывать объекты друг на друга, поэтому последняя запись выигрывает. Они не заменяют, что крайне важно.
- В верхней части этой конфигурации есть одна конфигурация, которая устанавливает baseUrl. Это не в
requirejs-config.js. Это вставляется во время компиляции Magento\Framework\RequireJs\Config.
Забудем на мгновение, как Magento работает, какие модули RequireJS требуют загрузки (возможно, хорошее обсуждение в другой раз; как подсказку, посмотрите mage/apply/main.js), давайте предположим, что у нас есть код:
require(['modulename'], function () {});
в вакууме где-то. Как Magento знает, что делать?
Ну, первое, что нужно сделать requireJS, это посмотреть modulenameего отображение. В нашем случае он узнает, что должен обрабатывать все запросы modulenameкак запрос к Module_Name/js/path/to/module. Он делает это только один раз. Отображения не являются рекурсивными. Я повторяю. Если у вас есть отображение от aдо bи от bдо a, это будет менять каждый запрос, и не вызовет бесконечный цикл.
После того, как мы пройдем через картографию, RequireJS рассмотрит, что у нее есть. Если он заканчивается .jsи не выглядит как абсолютная ссылка или URL-адрес, он будет добавлять предварительно настроенный baseUrlи загружать этот скрипт с помощью своих обычных процедур. Если он не заканчивается .jsи не является абсолютной ссылкой или URL-адресом, он будет добавлен .jsв конец, затем добавит сконфигурированный файл baseUrlи загрузится с помощью его обычных процедур. Если requireJS считает, что у него есть URL, он просто пытается загрузить его.