¿Cómo / dónde convierte Magento un nombre de módulo RequireJS en una URL?

8

En Magento 2, puede usar RequireJS para incluir un módulo de JavaScript con un código que se parece a esto.

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

Si bien el requirejs-config.jsarchivo es un poco de magia de Magento 2, este parece ser el RequireJS estándar. Básicamente, está asignando el nombre corto modulenameal módulo javascript llamado Package_Name/js/path/to/file.

Lo que no está claro es dónde o cómo Magento 2 convierte el nombre del módulo de JavaScript anterior

Package_Name/js/path/to/file

En la URL de HTTP (S)

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

En un sistema RequireJS de stock, RequireJS intentaría cargar la siguiente URL

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

Claramente, Magento está haciendo algo para garantizar que la URL anterior se convierta en una URL de interfaz de Magento. Lo que no está claro es

  1. ¿Dónde sucede esto (capa PHP? Capa Javascript?)
  2. Cuáles son las reglas para esa conversión. El módulo RequireJS no se parece a un identificador de archivo Magento estándar ( Package_Name::js/path/to/file)

Entonces, ¿cómo / dónde convierte Magento 2 / RequireJS el módulo en una ruta?

Alan Storm
fuente

Respuestas:

7

RequireJS tiene una característica que le permite establecer una baseUrl personalizada .

Magento genera baseUrl para RequireJS en el cuerpo de la página, donde se solicitan recursos JS. Entonces, es básicamente una parte más de la configuración RequireJS generada por Magento. Esta baseUrl se calcula en el lado del servidor y se basa en el tema actual, la configuración regional y la URL base para los archivos de vista estática de la tienda. Entonces la funcionalidad nativa RequireJS calcula la ruta completa de la siguiente manera

baseUrl + file + '.js'
BuskaMuza
fuente
Esto no parece responder a la pregunta que hice.
Alan Storm el
¿Podría, por favor, aclarar la pregunta? Magento sólo utiliza disponen de RequireJS baseUrl- requirejs.org/docs/api.html#config-baseUrl y para hacer que funcione adecuadamente genera baseUrlpara que sea igual //magento.example.com/static/frontend/Magento/luma/en_US/para la página. RequireJS simplemente lo concatena con la ruta del módulo: //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/filey agrega .js.
BuskaMuza
Información útil @BushaMuza, pero de nuevo, no es la pregunta que hice.
Alan Storm
1
Creo que es Vanilla RequireJS. Si se establece la etiqueta 'data-main' (que está en M2 por defecto), agregará la baseUrl que se está configurando en el archivo de referencias de BuskaMuza frente a la url de JS asignada. BaseUrl está configurado en la carpeta estática (con configuración regional), que es, por ejemplo //magento.example.com/static/frontend/Magento/luma/en_US/. Agréguelo Package_Name/js/path/to/file.jsy tendrá la URL completa. Creo que esto es lo que estás buscando; github.com/magento/magento2/blob/develop/lib/web/requirejs/…
Peter Jaap Blaakmeer
7

Te preguntas como

Module_Name/js/path/to/module

se convierte

//magento.example.com/static/frontend/Package/Theme/locale/Module_Name/js/path/to/module.js

En primer lugar, es importante comprender que esto es completamente necesario JS, no ninguna salsa especial de Magento (aunque hay algo de eso en otros lugares). En su mayor parte, el front-end usa solo el comportamiento normal de RequireJS. La magia generalmente está en cómo se genera pub/static, es decir, cómo view/area/web/js/path/to/module.jsse enlaza pub/static/area/Package/theme/Module_Name/js/path/to/module.js. Esto es manejado por el proceso de compilación de activos estáticos de Magento, y no voy a entrar aquí.

requirejs-config.js

Vamos a introducir un nuevo archivo, que usted menciona: requirejs-config.js. Esta es una salsa especial de Magento 2, pero probablemente no tanto como podría pensar.

Este archivo puede ser cualquier JavaScript, pero al menos debe declarar una variable (global) llamada config. El objeto vinculado a configse pasa directamente a requireJS para configurarlo.

La forma en que esto funciona es que Magento encuentra todo requirejs-config.jsen un proyecto. Estos pueden estar en un módulo, debajo view/areao en un tema, en su directorio raíz y en la anulación del módulo de un tema, por ejemplo Magento_Catalog/requirejs-config.js. Tenga en cuenta que esto no incluye ningún elemento secundario de un webdirectorio. Este archivo, en general, debería ser un hermano de un webdirectorio.

Una vez globalizado, cada archivo está decorado en un cierre (por lo que nuestra variable global no lo está), y una línea al final del cierre pasa la configvariable al requireobjeto. Esto puede ser visto:

Esto es 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' 
 }
 } 
};

Cuando llegue al front-end, se verá así:

(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);
})();

Esta decoración se puede ver en Magento\Framework\RequireJs\Config.

Cada uno de estos archivos decorados se concatena y se descarga static/_requirejs/area/Package/theme/locale/secure/requirejs-config.js. Esta ubicación se acuerda con anticipación, de modo que el HTML carga este script a medida que carga 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>

Considero cómo configurar RequireJS fuera del alcance de esta respuesta, pero tienen bastante buena documentación al respecto . Sin embargo, hay dos cosas importantes a tener en cuenta:

  1. Las llamadas sucesivas a require.configcapas colocarán objetos uno encima del otro, por lo que la última escritura gana. No reemplazan, lo cual es crucial.
  2. Hay una configuración en la parte superior de esta configuración que establece baseUrl. Esto no está en un requirejs-config.js. Esto se inserta en tiempo de compilación por Magento\Framework\RequireJs\Config.

Olvidando por un momento cómo funciona Magento, qué módulos RequireJS necesitan cargarse (una buena discusión para otro momento, tal vez; Como pista, mira mage/apply/main.js), supongamos que tenemos el código:

require(['modulename'], function () {});

en el vacío en alguna parte. ¿Cómo sabe Magento qué hacer?

Bueno, lo primero que requireJS hará es buscar modulenameen su mapeo. En nuestro caso, aprenderá que debe tratar todas las solicitudes modulenamecomo una solicitud Module_Name/js/path/to/module. Solo hace esto una vez. Las asignaciones no son recursivas. Repito. Si tiene una asignación de aa b, y de ba a, esto intercambiará cada solicitud y no causará un bucle infinito.

Una vez que hemos pasado por el mapeo brouhaha, RequireJS mira lo que tiene. Si termina .jsy no parece un enlace absoluto o una URL, antepondrá el configurado baseUrly cargará ese script a través de sus procedimientos normales. Si no termina .jsy no es un enlace absoluto o URL, se agregará .jsal final, luego antepondrá el configurado baseUrly se cargará a través de sus procedimientos normales. Si requireJS considera que tiene una URL, solo intenta cargarla.

Max Bucknell
fuente
OK, tengo este. La pieza que faltaba para mí era la configuración baseUrl de RequireJS. es decir, "RequireJS tiene una función que le permite establecer una baseUrl personalizada, Magento usa esta función y genera la baseURL en ese backend" requirejs.org/docs/api.html#config-baseUrl
Alan Storm
0

Está utilizando componentes más detalles que verifica Magento \ Framework \ View \ Element \ Js \ Componentes clase y proveedor de archivos de módulo predeterminado \ 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
fuente
Esto no parece responder a la pregunta que hice.
Alan Storm el