JavaScript resources in Magento

Overview

This topic describes the general concepts of how JavaScript components are organized in Magento.

To address the problem of slow page load, we exclude JavaScript from the page headers and we added the ability to use the RequireJS library.

RequireJS improves the perceived page load, time because it allows JavaScript to load in the background; in particular, because it enables asynchronous JavaScript loading.

Explore JavaScript resources

JS resources location

In Magento, you can find the JS components on the following levels:

  • Library level (lib/web). Resources located here are available in any place in Magento.
  • Module level (<module_dir>/view/<areaname>/web). If the module is enabled, resources added here are available in other modules and themes.
  • Theme level, for a particular module (<theme_dir>/<VendorName>_<ModuleName>/web). Resources added here are available for [inheriting] themes.
  • Theme level (<theme_dir>/web). Resources added here are available for [inheriting] themes.

Library level can only contain core Magento resources. Do not put custom JS files in the `lib/web` directory.

Specifying JS

We recommend specifying JavaScript resources in the templates rather than in the layout updates, to ensure processing of the resources in body of a page.

Accessing JS resources

JS resources are accessed using relative paths.

Example 1

  • File actual location: app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js
  • File published to pub/static: pub/static/frontend/Magento/<theme>/<locale>/Magento_ConfigurableProduct/js/configurable.js. Here <theme> and <locale> are the currently applied in your instance theme and locale .
  • Called in script:
      require(["Magento_ConfigurableProduct/js/configurable"], function(Configurable){
         });
    

Example 2

  • File actual location: app/code/design/frontend/Magento/blank/web/js/theme.js
  • File published to pub/static: pub/static/frontend/Magento/<theme>/<locale>/js/theme.js
  • Called in script:
      require(["js/theme.js"], function(){
         });
    

Example 3

  • File actual location: lib/web/jquery.js
  • File published to pub/static: pub/static/<area>/Magento/<theme>/<locale>/jquery.js
  • Called in script:
      require(["jquery"], function($){
         });
    

These relative paths are also used in for mapping and setting paths in requirejs-config.js configuration files.

Dependencies between JavaScript resources

To build a dependency on the third-party plugin, specify a [shim] in the following configuration files:

  • requirejs-config.js

     var config = {
         "shim": {
         "3-rd-party-plugin": ["jquery"]
         }
     };
    
  • <third-party-plugin>.js

     !(function($){
         // plugin code
         // where $ == jQuery
     })(jQuery);
    

RequireJS library

Including RequireJS

To be available for the entire Magento instance, RequireJS library is included in the following layout files:

  • For the adminhtml area:

    app/code/Magento/Backend/view/adminhtml/layout/default.xml

     <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
         <head>
             <title>Magento Admin</title>
             <meta name="viewport" content="width=1024"/>
             <meta name="format-detection" content="telephone=no"/>
         <!-- Here's the library included -->
         <link src="requirejs/require.js"/>
             <css src="extjs/resources/css/ext-all.css"/>
             <css src="extjs/resources/css/ytheme-magento.css"/>
         </head>
         <body>
             <attribute name="id" value="html-body"/>
             <!-- Here's the basic configuration file require_js.phtml specified -->
         <block name="require.js" class="Magento\Backend\Block\Page\RequireJs" template="Magento_Backend::page/js/require_js.phtml"/>
             <referenceContainer name="global.notices">
                 <block class="Magento\Backend\Block\Page\Notices" name="global_notices" as="global_notices" template="page/notices.phtml"/>
             </referenceContainer>
             <referenceContainer name="header">
                 ...
         </referenceContainer>
             <referenceContainer name="after.body.start">
                 <!-- Here's the main configuration file requirejs-config.js specified -->
             <block class="Magento\RequireJs\Block\Html\Head\Config" name="requirejs-config"/>
                 <block class="Magento\Translation\Block\Html\Head\Config" name="translate-config"/>
                 <block class="Magento\Translation\Block\Js" name="translate" template="Magento_Translation::translate.phtml"/>
                 <block class="Magento\Framework\View\Element\Js\Components" name="head.components" as="components" template="Magento_Backend::page/js/components.phtml"/>
                 <block class="Magento\Framework\View\Element\Html\Calendar" name="head.calendar" as="calendar" template="Magento_Backend::page/js/calendar.phtml"/>
             </referenceContainer>
         </body>
     </page>
    
  • For the frontend area the similar configuration is located in app/code/Magento/Theme/view/frontend/layout/default.xml.

Mapping JS resources

To make the configurations more precise and specific for different modules/themes, requirejs-config.js files can be placed in different locations depending on your needs.

All configurations are collected and executed in the following order:

  1. Library configurations.
  2. Configurations at the module level.
  3. Configurations at the theme module level for the ancestor themes.
  4. Configurations at the theme module level for a current theme.
  5. Configurations at the theme level for the ancestor themes.
  6. Configurations at the theme level for the current theme.

The baseUrl parameter for RequireJS is specified in the following files:

About AMD modules and RequireJS [RequireJS library]: http://requirejs.org [inheriting]: /guides/v2.2/frontend-dev-guide/themes/theme-inherit.html [shim]: http://requirejs.org/docs/api.html#config-shim