Как / Где Magento конвертирует имя модуля RequireJS в URL?

8

В Magento 2 вы можете использовать RequireJS для включения модуля javascript с кодом, который выглядит примерно так.

#File: app/code/Package/Name/view/frontend/requirejs-config.js
var config = {
    map: {
        '*': {
            modulename: 'Package_Name/js/path/to/file'
        }
    }
}

Несмотря на то, что requirejs-config.jsфайл немного волшебен в Magento 2, он выглядит как стандартный RequireJS. Вы в основном сопоставляете короткое имя modulenameс модулем javascript с именем Package_Name/js/path/to/file.

Что не ясно, так это где и как Magento 2 преобразует имя модуля javascript выше

Package_Name/js/path/to/file

В HTTP (S) URL

//magento.example.com/static/frontend/Magento/luma/en_US/Package_Name/js/path/to/file.js

В стандартной системе RequireJS RequireJS попытается загрузить следующий URL

//magento.example.com/Package_Name/js/path/to/file.js

Очевидно, что Magento делает что-то, чтобы вышеуказанный URL был преобразован в внешний интерфейс Magento. Что не ясно, так это

  1. Где это происходит (уровень PHP? Уровень Javascript?)
  2. Каковы правила для этого преобразования. Модуль RequireJS не похож на стандартный идентификатор файла Magento ( Package_Name::js/path/to/file)

Итак, как / где Magento 2 / RequireJS преобразует модуль в путь.

Алан Сторм
источник

Ответы:

7

RequireJS имеет функцию, которая позволяет вам установить пользовательский baseUrl .

Magento генерирует baseUrl для RequireJS в теле страницы, где запрашиваются ресурсы JS. Итак, это в основном еще одна часть конфигурации RequireJS, сгенерированной Magento. Этот baseUrl рассчитан на стороне сервера и основан на текущей теме, локали и базовом URL для файлов статического представления для магазина. Затем собственная функция RequireJS рассчитывает полный путь следующим образом

baseUrl + file + '.js'
BuskaMuza
источник
Кажется, это не отвечает на вопрос, который я задал.
Алан Сторм
Не могли бы вы уточнить вопрос? Magento просто использует функцию RequireJS baseUrl- requirejs.org/docs/api.html#config-baseUrl, и чтобы она работала должным образом, генерируется baseUrlравной //magento.example.com/static/frontend/Magento/luma/en_US/странице. RequireJS просто объединяет его с путем модуля: //magento.example.com/static/frontend/Magento/luma/en_US/ + Package_Name/js/path/to/file -> //magento.example.com/static/frontend/Magento/luma/en_US/Package_Name/js/path/to/fileи добавляет .js.
BuskaMuza
Здесь baseUrlгенерируется - github.com/magento/magento2/blob/develop/app/code/Magento/Theme/...
BuskaMuza
Полезная информация @BushaMuza, но опять же, не тот вопрос, который я задал.
Алан Сторм
1
Я думаю, что это ванильный RequireJS. Если установлен тег «data-main» (который используется по умолчанию в M2), он добавит baseUrl, который устанавливается в файле BuskaMuza, перед указанным URL-адресом JS. Для baseUrl задана статическая папка (с локалью), например //magento.example.com/static/frontend/Magento/luma/en_US/. Добавьте Package_Name/js/path/to/file.jsк нему, и вы получите полный URL. Я думаю, что это то, что вы ищете; github.com/magento/magento2/blob/develop/lib/web/requirejs/…
Питер Яап Блаакмир
7

Вам интересно, как

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 за рамками этого ответа, но у них есть довольно хорошая документация по этому вопросу . Однако следует отметить две важные вещи:

  1. Последовательные вызовы require.configбудут накладывать объекты друг на друга, поэтому последняя запись выигрывает. Они не заменяют, что крайне важно.
  2. В верхней части этой конфигурации есть одна конфигурация, которая устанавливает 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, он просто пытается загрузить его.

Макс Бакнелл
источник
Хорошо, у меня есть этот Недостающим элементом для меня была конфигурация RequireJS baseUrl. т.е. «RequireJS имеет функцию, позволяющую установить пользовательский baseUrl, Magento использует эту функцию и генерирует baseURL для этого бэкенда
Alan Storm
0

Он использует компоненты, более подробно вы можете проверить Magento \ Framework \ View \ Element \ Js \ Components класс и файл по умолчанию для модуля module vendor \ magento \ module-catalog \ view \ frontend \ layout \ default.xml

<referenceContainer name="after.body.start">
        <block class="Magento\Framework\View\Element\Js\Components" name="head.components" as="components" template="Magento_Catalog::js/components.phtml"/>
    </referenceContainer>
Pratik
источник
Кажется, это не отвечает на вопрос, который я задал.
Алан Сторм