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)网址

//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前端URL。不清楚的是

  1. 发生这种情况的地方(PHP层?JavaScript层?)
  2. 转换的规则是什么。RequireJS模块看上去不像标准的Magento文件标识符(Package_Name::js/path/to/file

因此,Magento 2 / RequireJS如何/在何处将模块转换为路径。

Answers:


7

RequireJS具有允许您设置自定义baseUrl的功能

Magento在页面主体中为RequireJS生成baseUrl,在其中请求JS资源。因此,它基本上是Magento生成的RequireJS配置的另一部分。此baseUrl在服务器端计算,并且基于商店的静态视图文件的当前主题,区域设置和基本URL。然后,本机RequireJS功能将按以下方式计算完整路径

baseUrl + file + '.js'

这似乎无法回答我提出的问题。
艾伦·风暴

您能否澄清这个问题?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


有用的信息@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目录的同级文件。

遍历所有文件后,每个文件都用闭包修饰(因此实际上不是全局变量),并且闭包末尾的一行将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。它只会执行一次。映射不是递归的。我重复。如果您具有从ab和从b到的映射a,则这将交换每个请求,并且不会导致无限循环。

一旦完成了映射问题,RequireJS就会查看它的功能。如果它以结尾.js,并且看起来不像是绝对链接或URL,它将在已配置的baseUrl脚本之前,并通过其正常过程加载该脚本。如果它不是结尾,.js也不是绝对链接或URL,它将添加.js到结尾,然后在已配置的内容之前添加baseUrl并通过其正常过程加载。如果requireJS认为它具有URL,它将尝试加载该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>

这似乎无法回答我提出的问题。
艾伦·斯托姆
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.