Wie / Wo konvertiert Magento den Namen eines RequireJS-Moduls in eine URL?

8

In Magento 2 können Sie RequireJS verwenden, um ein Javascript-Modul mit Code einzuschließen, der ungefähr so ​​aussieht.

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

Während die requirejs-config.jsDatei ein bisschen Magento 2-Magie ist, scheint dies Standard RequireJS zu sein. Grundsätzlich ordnen Sie den Kurznamen modulenamedem genannten Javascript-Modul zu Package_Name/js/path/to/file.

Unklar ist, wo oder wie Magento 2 den oben genannten Namen des Javascript-Moduls konvertiert

Package_Name/js/path/to/file

In die HTTP (S) URL

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

In einem Standard-RequireJS-System würde RequireJS versuchen, die folgende URL zu laden

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

Es ist also klar, dass Magento etwas unternimmt, um sicherzustellen, dass die obige URL in eine Magento-Frontend-URL konvertiert wird. Was nicht klar ist, ist

  1. Wo passiert das (PHP-Schicht? Javascript-Schicht?)
  2. Was ist die Regel für diese Konvertierung? Das RequireJS-Modul sieht nicht wie eine Standard-Magento-Dateikennung aus ( Package_Name::js/path/to/file)

Wie / wo konvertiert Magento 2 / RequireJS das Modul in einen Pfad?

Alan Storm
quelle

Antworten:

7

RequireJS verfügt über eine Funktion, mit der Sie eine benutzerdefinierte baseUrl festlegen können .

Magento generiert baseUrl für RequireJS im Hauptteil der Seite, auf der JS-Ressourcen angefordert werden. Es ist also im Grunde ein weiterer Teil der von Magento generierten RequireJS-Konfiguration. Diese baseUrl wird serverseitig berechnet und basiert auf dem aktuellen Thema, dem Gebietsschema und der Basis-URL für statische Ansichtsdateien für den Store. Die native RequireJS-Funktionalität berechnet dann den vollständigen Pfad wie folgt

baseUrl + file + '.js'
BuskaMuza
quelle
Dies scheint die von mir gestellte Frage nicht zu beantworten.
Alan Storm
Könnten Sie bitte die Frage klären? Magento verwendet nur die RequireJS-Funktion von baseUrl- requirejs.org/docs/api.html#config-baseUrl, und damit es ordnungsgemäß funktioniert, wird baseUrles //magento.example.com/static/frontend/Magento/luma/en_US/für die Seite gleich generiert . RequireJS verkettet es nur mit dem Pfad des Moduls: //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/fileund fügt hinzu .js.
BuskaMuza
Nützliche Informationen @BushaMuza, aber auch hier nicht die Frage, die ich gestellt habe.
Alan Storm
1
Ich denke, es ist Vanille RequireJS. Wenn das Tag 'data-main' festgelegt ist (dies ist die Standardeinstellung M2), wird die baseUrl hinzugefügt, die in der Datei BuskaMuza-Referenzen vor der zugeordneten JS-URL festgelegt wird. Die baseUrl wird beispielsweise auf den statischen Ordner (mit Gebietsschema) gesetzt //magento.example.com/static/frontend/Magento/luma/en_US/. Wenn Package_Name/js/path/to/file.jsSie es hinzufügen, haben Sie die vollständige URL. Ich denke, das ist es, wonach Sie suchen. github.com/magento/magento2/blob/develop/lib/web/requirejs/…
Peter Jaap Blaakmeer
7

Sie fragen sich, wie

Module_Name/js/path/to/module

wird

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

Zuallererst ist es wichtig zu verstehen, dass dies ausschließlich JS erfordert, keine Magento-Spezialsauce (obwohl es einige davon anderswo gibt). Zum größten Teil verwendet das Front-End nur das normale Verhalten von RequireJS. Die Magie liegt normalerweise darin, wie sie erzeugt wird pub/static, nämlich wie sie miteinander verbunden view/area/web/js/path/to/module.jsist pub/static/area/Package/theme/Module_Name/js/path/to/module.js. Dies wird durch den statischen Asset-Kompilierungsprozess von Magento erledigt, und ich werde hier nicht darauf eingehen.

requirejs-config.js

Lassen Sie uns eine neue Datei vorstellen, die Sie erwähnen : requirejs-config.js. Dies ist eine Magento 2-Spezialsauce, aber wahrscheinlich nicht so viel, wie Sie vielleicht denken.

Diese Datei kann ein beliebiges JavaScript sein, sollte jedoch mindestens eine (globale) Variable mit dem Namen deklarieren config. Das an gebundene Objekt configwird direkt an requireJS übergeben, um es zu konfigurieren.

So funktioniert das: Magento findet alles requirejs-config.jsin einem Projekt. Diese können sich in einem Modul unter view/areaoder in einem Thema in seinem Stammverzeichnis und in der Modulüberschreibung eines Themas befinden, z Magento_Catalog/requirejs-config.js. Beachten Sie, dass dies kein untergeordnetes Element eines webVerzeichnisses enthält. Diese Datei sollte im Allgemeinen ein Geschwister eines webVerzeichnisses sein.

Nach dem Globbed wird jede Datei in einem Abschluss dekoriert (unsere globale Variable also nicht), und eine Zeile am Ende des Abschlusses übergibt die configVariable an das requireObjekt. Das kann man sehen:

Dies ist 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' 
 }
 } 
};

Wenn es zum Frontend kommt, sieht es so aus:

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

Diese Dekoration ist in zu sehen Magento\Framework\RequireJs\Config.

Jede dieser dekorierten Dateien wird verkettet und abgelegt static/_requirejs/area/Package/theme/locale/secure/requirejs-config.js. Dieser Speicherort wird im Voraus vereinbart, sodass der HTML-Code dieses Skript beim Laden vonJS lädt:

<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>

Ich überlege, wie RequireJS für diese Antwort außerhalb des Gültigkeitsbereichs konfiguriert werden kann, aber sie haben eine ziemlich gute Dokumentation dazu . Es gibt jedoch zwei wichtige Dinge zu beachten:

  1. Durch aufeinanderfolgende Aufrufe require.configwerden Objekte übereinander gelegt, sodass der letzte Schreibvorgang gewinnt. Sie ersetzen nicht, was entscheidend ist.
  2. Oben in dieser Konfiguration befindet sich eine Konfiguration, mit der baseUrl festgelegt wird. Dies ist nicht in einem requirejs-config.js. Dies wird zur Kompilierungszeit von eingefügt Magento\Framework\RequireJs\Config.

Vergessen mage/apply/main.jswir für einen Moment, wie Magento herausfindet, welche RequireJS-Module geladen werden müssen (vielleicht eine gute Diskussion für ein anderes Mal; als Hinweis, schauen Sie rein), nehmen wir an, wir haben den Code:

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

irgendwo im luftleeren Raum. Woher weiß Magento, was zu tun ist?

Nun, das erste, was erfordert, dass JS modulenamein seiner Zuordnung nachschlägt . In unserem Fall wird es lernen, dass es alle Anfragen modulenameals eine Anfrage an behandeln sollte Module_Name/js/path/to/module. Das macht es nur einmal. Zuordnungen sind nicht rekursiv. Ich wiederhole. Wenn Sie eine Zuordnung von anach bund von bnach haben a, tauscht dies jede Anforderung aus und verursacht keine Endlosschleife.

Sobald wir das Mapping brouhaha durchlaufen haben, schaut RequireJS, was es hat. Wenn es endet .jsund nicht wie ein absoluter Link oder eine URL aussieht, wird das konfigurierte baseUrlSkript vorangestellt und das Skript gemäß den normalen Verfahren geladen. Wenn es nicht endet .jsund kein absoluter Link oder keine absolute URL ist, wird .jses am Ende hinzugefügt , dann wird das Konfigurierte vorangestellt baseUrlund durch seine normalen Verfahren geladen. Wenn requireJS davon ausgeht, dass es eine URL hat, versucht es nur, diese zu laden.

Max Bucknell
quelle
OK, ich habe diesen hier. Das fehlende Teil für mich war die baseUrl-Konfiguration von RequireJS. dh "RequireJS hat eine Funktion, mit der Sie eine benutzerdefinierte baseUrl festlegen können. Magento verwendet diese Funktion und generiert die baseURL in diesem Backend." requirejs.org/docs/api.html#config-baseUrl
Alan Storm
0

Es werden Komponenten verwendet, die detaillierter sind. Überprüfen Sie die Klasse Magento \ Framework \ View \ Element \ Js \ Components und den Standardmoduldatei-Hersteller \ 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
quelle
Dies scheint die von mir gestellte Frage nicht zu beantworten.
Alan Storm