JavaScript (Basics)
Given a scenario, work with JavaScript files: RequireJS module paths and aliases, module types, initialization patterns, and JS mixins.
JavaScript Basics in Magento
RequireJS & Module Resolution
- Location: Modules are
.jsfiles inview/(frontend|adminhtml|base)/web/js/. - Naming convention:
Module_Name/path/to/filemaps toview/.../web/js/path/to/file.js. - Example:
Magento_Catalog/js/product/view/product-info→Magento_Catalog/view/frontend/web/js/product/view/product-info.js.
Aliases via requirejs-config.js
var config = {
map: {
'*': {
compareList: 'Magento_Catalog/js/list',
relatedProducts: 'Magento_Catalog/js/related-products',
upsellProducts: 'Magento_Catalog/js/upsell-products',
productListToolbarForm: 'Magento_Catalog/js/product/list/toolbar',
catalogGallery: 'Magento_Catalog/js/gallery',
catalogAddToCart: 'Magento_Catalog/js/catalog-add-to-cart'
}
}
};
Now compareList resolves to Magento_Catalog/js/list.
Types of JavaScript Modules
Plain AMD Modules
General-purpose modules; when used with Magento initializers, return a function.
define(['jquery'], function ($) {
'use strict';
function handleWindow() {
// ...
}
// Return a callback if used with data-mage-init or x-magento-init
return function (element, config) {
handleWindow();
window.addEventListener('resize', handleWindow);
// element is the DOM node; config is the JSON config
};
});
jQuery UI Widgets
Declare a jQuery UI widget; return the widget for reuse.
define(['jquery'], function ($) {
'use strict';
$.widget('mage.modal', {
options: {
// default options
},
setTitle: function () {},
_setKeyListener: function () {}
});
return $.mage.modal;
});
UI Components (uiElement)
UI Component modules extend uiElement; they expose defaults and methods used in Knockout templates.
define(['uiElement'], function (Element) {
'use strict';
return Element.extend({
defaults: {
links: {
value: '${ $.provider }:${ $.dataScope }'
}
},
hasService: function () {},
initObservable: function () {
this._super().observe('disabled visible value');
return this;
}
});
});
Executing Modules
data-mage-init (attribute)
<div
class="example"
data-mage-init='{"Bonlineco_Module/js/modal": {"configuration-value": true}}'>
</div>
Magento loads the module and calls the returned function with (element, config).
x-magento-init (script)
<script type="text/x-magento-init">
{
".element-selector": {
"Bonlineco_Module/js/modal": { "configuration-value": true }
},
"*": {
"Vendor_Module/js/log": {}
}
}
</script>
- Selector matches multiple nodes → module instantiated per node.
- Selector
*passesfalseas the node argument.
Imperative require() (not recommended)
require(['jquery', 'Magento_Catalog/js/list'], function ($, list) {
// Do work
});
Use initializers when possible; imperative patterns are acceptable for quick scripts.
Customizing Native JavaScript
Fallback Override
Copy a core JS file into your theme/module path to replace it. Heavier maintenance; avoid when a mixin suffices.
Mixins (Preferred)
Like PHP plugins for JS. Add behavior before/after/around existing functions without overriding the file.
requirejs-config.js
var config = {
config: {
mixins: {
'Magento_Checkout/js/view/shipping': {
'Vendor_Module/js/mixin/shipping-mixin': true
}
}
}
};
Mixin file
define([], function () {
'use strict';
return function (Target) {
return Target.extend({
setShippingInformation: function () {
// before/after custom logic
this._super();
}
});
};
});
Works well when the core is designed for extension; falls back to overrides when necessary.
Further Reading
Exam Tips
- Path mapping:
Module_Name/path/to/file→view/.../web/js/path/to/file.js - Aliases:
requirejs-config.jsmap:{'*':{ alias:'Module/js/file' }} - Initializers:
data-mage-initandx-magento-initcall returned function with(element, config) - UI Components: extend
uiElement, usedefaults,initObservable - Customize: Prefer JS mixins over full overrides