Вам интересно, как
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, он просто пытается загрузить его.