requireJS在Magento中的应用

更新

本主题通过示例描述了在 Magento 中如何使用 RequireJS 库的一般概念。 详细解释请参考RequireJS官方文档。

RequireJS 是一个 JavaScript 文件和模块加载器。 它改善了感知页面加载时间,因为它允许 JavaScript 在后台加载。 特别是,它支持异步 JavaScript 加载。

RequireJS 在Magento中的配置

所有配置都在 requirejs-config.js 文件中完成。 它有一个单一的根对象配置,其中包含下面描述的配置选项。 所有配置设置都是可选的,仅在需要时使用。 以下代码段是描述文件结构的 requirejs-config.js 示例。 示例 requirejs-config.js 文件


var config = {
    map: {...},
    paths: {...},
    deps: [...],
    shim: {...},
    config: {
        mixins: {...},
        text: {...}
    }
}

map

map配置映射(连接)任何真正的AMD模块,调用define(),到指定的alias。在下面的片段中,*意味着所有加载的RequireJS模块可以使用指定的别名。第二个映射只适用于Vendor_Module/js/amd-module的上下文。所以,两种类型的上下文都可以应用:要么是全局上下文,要么是特定模块的上下文。

The map configuration maps (connects) any real AMD modules that calls define(), to the specified alias. In the snippet below, * means all loaded RequireJS modules can use the specified alias. The second mapping applies only in the context of Vendor_Module/js/amd-module. So, both types of contexts can be applied: either a global context, or a module specific context.

map: {
    '*': {
        alias: 'Vendor_Module/js/complex/path/amd-module'
    },
    'Vendor_Module/js/amd-module': {
        alias-two: 'Vendor_Module/js/complex/path/amd-module-two'
    }
}

Now we can use our Vendor_Module/js/complex/path/module using alias in any RequireJS module or config file without needing to type the entire path. For example, in Magento, catalogAddToCart is mapped to Magento_Catalog/js/catalog-add-to-cart and can be used anywhere as a RequireJS module name. In the next example, catalogAddToCart is mapped to Magento_Catalog/js/catalog-add-to-cart only in the context of the discountCode module.

现在我们可以在任何RequireJS模块或配置文件中使用我们的Vendor_Module/js/complex/path/module的别名,而不需要输入整个路径。例如,在Magento中,catalogAddToCart被映射到Magento_Catalog/js/catalog-add-to-cart,并且可以在任何地方作为RequireJS模块名称使用。在下一个例子中,catalogAddToCart被映射到Magento_Catalog/js/catalog-add-to-cart,只在discountCode模块中使用。

map: {
    '*': {
        catalogAddToCart: 'Magento_Catalog/js/catalog-add-to-cart'
    },
    'discountCode': {
        catalogAddToCart: 'Magento_Catalog/js/catalog-add-to-cart'
    }
}

You can also use the map configuration to override a JS module with a custom JS module. See Custom JS component.

paths

The paths configuration, similar to map, is used for aliasing not just any real AMD module that calls define(), but also any JS file (even from a URL), HTML templates, etc. Magento uses this to alias URLs and third party libraries.

路径配置,类似于map,不仅用于别名任何调用define()的真正的AMD模块,还用于别名任何JS文件(甚至来自URL)、HTML模板等。Magento使用它来别名URL和第三方库。

paths: {
    'alias': 'library/file',
    'another-alias': 'https://some-library.com/file'
}

When setting a path to an array with multiple script sources, if the first script fails to load, the next is used as a fallback.

var config = {
    ...
    paths: {
        'alias': [
            'https://some-library.com/file',
            'vendor_name>_<module_name>/js/file'
        ]
    }
};

对于外部内容,应将资源列入白名单;否则Magento会在浏览器控制台中发出错误通知。请参阅内容安全策略(Content Security Policies)。

考虑一下覆盖adminhtml中的一个HTML文件的例子。在这个例子中,adminhtml中的文本框的最大长度值被改变了。该HTML文件位于 vendor/magento/module_ui/view/base/web/templates/form/element/input.html。

  1. 在app/code/<Vendor_Name>/<Module_Name>/view/base/下创建一个requirejs-config.js文件并添加以下代码。

    
    var config = {
         paths: {
             'ui/template/form/element/input': '<vendor_name>_<module_name>/template/form/element/input'
         }
     };
    
    
  2. 在app/code/<Vendor_Name>/<Module_Name>/view/base/web/template/form/下创建一个input.html文件,并从module_ui模板文件复制input.html文件的内容。

  3. 将最大长度值改为512,原来设置为256。

  4. 升级应用

    bin/magento setup:upgrade
    
  5. 生成以来注入配置

    bin/magento setup:di:compile
    
  6. 通过检查元素的源代码来确认修改,并检查最大长度值,它应该是模板中规定的512。

在module_ui的requirejs-config.js模块中,Magento_Ui/template的路径被设置为ui/template,因此ui/template被用于指定路径。如果没有设置路径,应使用<module_name>/templates。

deps

deps配置是用来添加一个依赖关系的。它既可以在var config = {}下直接使用,也可以在shim配置下使用。在一个独立的deps配置下添加模块将在所有页面中加载指定的模块。

在这个片段中,自定义的Vendor_Module/js/module将被加载到所有页面中。


deps: ['Vendor_Module/js/module']

shim

shim配置用于建立对第三方库的依赖,因为我们不能修改它。

什么时候使用 shim 配置:

  • 为第三方库添加一个新的依赖关系

  • 向不使用AMD模块的第三方库添加新的依赖关系

  • 通过向第三方库添加依赖关系来改变加载顺序

    在这个片段中,依赖被直接添加到一个数组中,或者它可以被指定为deps键下的数组。exports键用于指定模块被导出到什么标识符下。这个出口标识符可以用来访问它。

shim: {
    '3rd-party-library': ['myJSFile'],
    'another-3rd-party-library': {
        deps: ['myJSFile'],
        exports: 'another3rdPartyLibrary'
    }
}

mixins

mixins配置用于覆盖AMD模块的组件方法,该模块返回一个UI组件、一个jQuery widget或一个JS对象。与上述配置属性不同,mixins属性在config属性下,除了名为config的父对象外。

在这个片段中,Vendor_Module/js/module-mixin将用指定的组件方法覆盖Vendor_Module/js/module中的现有组件方法。在原始路径/to/js后面加一个-mixin来命名mixin是一种惯例,尽管不是必须的。

config: {
    mixins: {
        'Vendor_Module/js/module': {
            'Vendor_Module/js/module-mixin': true
        }
    }
}

Javascript mixins 的概念本身在使用Javascript混合器中得到了深入解释。

text

The text configuration is used to set the security request headers using the text.js file.

Without Cross Origin Resource Sharing (CORS) it is not possible to add the X-Requested-With header to a cross domain XHR request. Set this header to tell the server that the request was initiated from the same domain.

config: {
    text: {
        'headers': {
            'X-Requested-With': 'XMLHttpRequest'
        }
    }
}