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

したがって、上記のURLがMagentoフロントエンドURLに確実に変換されるようにするために、Magentoが何らかの処理を行っていることは明らかです。はっきりしないのは

  1. これが起こる場所(PHPレイヤー?JavaScriptレイヤー?)
  2. その変換のルールは何ですか。RequireJSモジュールが標準のMagentoファイル識別子(Package_Name::js/path/to/file)のように見えない

したがって、Magento 2 / RequireJSはどのように/どこでモジュールをパスに変換しますか?

回答:


7

RequireJSには、カスタムbaseUrlを設定できる機能があります。

Magentoは、JSリソースがリクエストされるページの本文にRequireJSのbaseUrlを生成します。したがって、これは基本的にMagentoによって生成されるRequireJS構成のもう1つの部分です。このbaseUrlはサーバー側で計算され、ストアの静的ビューファイルの現在のテーマ、ロケール、およびベースURLに基​​づいています。次に、ネイティブのRequireJS機能が次のようにフルパスを計算します

baseUrl + file + '.js'

これは私が尋ねた質問に答えていないようです。
アランストーム

質問を明確にしていただけませんか?Magentoは、-requirejs.org/docs/api.html#config baseUrl- baseUrlの RequireJS機能を使用し、適切に機能させることで、ページ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


有用な情報@BushaMuzaですが、私が尋ねた質問ではありません。
アランストーム

1
それはバニラRequireJSだと思います。'data-main'タグが設定されている場合(これはデフォルトのM2です)、マップされたJS URLの前にBuskaMuza参照ファイルで設定されているbaseUrlを追加します。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/...
ピーター・ヤープBlaakmeer

7

あなたはどう思いますか

Module_Name/js/path/to/module

なる

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

まず第一に、これは完全にrequireJSであり、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ディレクトリの兄弟である必要があります。

globされると、各ファイルはクロージャーで装飾され(そのため、グローバル変数は実際にはそうではありません)、クロージャーの最後の行は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を構成する方法を検討していますが、これについてはかなり良いドキュメントがあります。ただし、注意すべき重要な点が2つあります。

  1. を連続して呼び出すと、require.configオブジェクトが互いの上に重ねられるため、最後の書き込みが優先されます。それらは置き換えられません、これは重要です。
  2. この構成の上部には、baseUrlを設定する構成が1つあります。これはにありません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。これを行うのは1回だけです。マッピングは再帰的ではありません。繰り返します。あなたからのマッピングを持っている場合ab、そしてからba、これは各要求を交換し、無限ループを引き起こすことはありません。

マッピング問題を通過すると、RequireJSはそれが何であるかを調べます。末尾がで.js、絶対リンクまたはURLのように見えない場合は、構成済みの先頭に追加され、baseUrl通常の手順でそのスクリプトをロードします。末尾.jsがなく、絶対リンクまたはURLでない場合.js、末尾に追加され、構成済みの先頭に追加されbaseUrlて、通常の手順で読み込まれます。requireJSがURLを認識している場合は、それをロードしようとします。


はい、これを持っています。私にとって欠けていたのは、RequireJSのbaseUrl構成でした。つまり、「RequireJSにはカスタムbaseUrlを設定できる機能があり、Magentoはこの機能を使用して、そのバックエンドにbaseURLを生成します」requirejs.org/docs/api.html#config-baseUrl
Alan Storm

0

Magento \ Framework \ View \ Element \ Js \ Componentsクラスとデフォルトのモジュールファイル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>

これは私が尋ねた質問に答えていないようです。
アランストーム
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.