Magento 2 uses RequireJs.

Custom js files live in app/code/[codePool]/[Vendor]/[ModuleName]/view/frontend/web/js

These custom js files are referred to as “modules” and are self contained.

Let’s look at a basic js module.

In [modulename].js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
define([
    'jquery',
    'jquery/ui'
], function($) {
    $.widget('[ns].[modulename]', {
        _create: function() {
            if (console) {
                console.log(this.element);
            }
        }
    });

    return $.[ns].[modulename];
});

Here we are creating a module using a jQuery widget that will log the current element to the console. [ns] is simple a namespace. It is required for jQuery widgets. For example, Magento use ‘mage’. I use ‘smartie’.

[modulename] is just a descriptive name for the module you creating. The above module just adds a highlight class to an element. It might be appropriate to call it ‘highlight’.

The define() function is directly from requireJs. In the above it takes two arguments. The first is an array of dependencies. The second is a definition function that gets called once all of the dependencies are loaded. The function should return an object that defines our module. In this case, we return a jQuery widget ($.[ns].[modulename]).

Note the dependencies are also passed as parameters to the definition function in the order that they are specified.

Ok great but how do i load this module on the frontend?

Firstly we must declare the module;

The following is not strictly required but it will not only enable us to alias our module but it also allows other requirejs functionality to be applied to our module later on.

To do this, Magento uses a requirejs-config.js. For example;

In view/frontend/requirejs-config.js:

var config = {
    map: {
        '*': {
            '[alias]' : '[Vendor_ModuleName]/js/[modulename]'
        }
    }
};

[alias] is just a short name for the path. You will use it later in your template. It is normal for the alias to be similar if not the same to the [modulename] but it can be whatever you want it to be just as long as it is unique.

[Vendor]_[ModuleName]/js/highlight is a (magic) path to our custom javascript file that will eventually reside in pub/static/frontend/[Package]/[theme]/[lang]/[Vendor]_[ModuleName]/js/highlight.js but it first locates the real file by expanding the above path to app/code/[codePool]/[Vendor]/[ModuleName]/view/frontend/web/js/highlight.js

Note that you never include the .js extension on the end of the path. It will be added for you.

You then use a special script tag inside a template file with a type attribute of text/x-magento-init

It looks like…

<script type="text/x-magento-init">
{
    "#foo": {
        "[alias]": {'param': 123}
    }
}
</script>

At a basic level, Magento looks for script tags with the special type attribute and then processes the data within. It then removes the scripts from the DOM.

#foo is the selector of the element that we want to trigger our module on.

The [alias] is the same as what you declared in the requirejs-config.js above

The final bit is a way for you to pass arguments to the module ({‘param’: 123}).

If all has gone well, open up the console and you should see the element printed out.

The above code examples can be found on my github account

  • magento2
  • javascript
  • requirejs

Like this post? Share it :)


Related Posts

Back