您想知道如何
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,但是他们对此有相当不错的文档。但是,有两点需要注意:
- 连续调用
require.config
将使对象彼此重叠,因此最后写入将获胜。它们不会替代,这至关重要。
- 此配置的顶部有一个配置,用于设置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,它将尝试加载该URL。