Max Bucknell & Marcin Szterling
Taming the JavaScript Beast in Magento 2
Ujarzmić JavaScript w Magento 2
Slide 2
Slide 2 text
No content
Slide 3
Slide 3 text
Take a Deep Breath
• What's Changed for M2?
• RequireJS
• JavaScript Components
• jQuery UI Widgets
• UI Apps
Slide 4
Slide 4 text
What's Changed?
• No more Prototype
• No more inline scripts
• No more adding JS to the
• No more global variables
• And a bunch of new stuff
Slide 5
Slide 5 text
RequireJS
Slide 6
Slide 6 text
RequireJS
• A JavaScript module loader
• 1.0 in 2011
• Loads JavaScript on a page.
• Loads a "module", and its dependencies, and its
dependencies, and so on.
Slide 7
Slide 7 text
AMD
• Not a chip manufacturer
• Stands for "Asynchronous Module Definition"
• The format of RequireJS "modules"
• Used in all Magento 2 JavaScript files
Module Definition
• To define an AMD module, you write a function
• This function will be called once when your
module is loaded
• Whatever you return is what dependents get, your
public API
Slide 13
Slide 13 text
RequireJS – Impacts
• All JavaScript is loaded after your content
• Separation of concerns
• No global scope pollution
Slide 14
Slide 14 text
AMD Dependencies
• How does RequireJS know what jquery means?
• ...or collapsible?
• ...or mage/translate?
• ...or Magento_Checkout/js/view/sidebar?
Slide 15
Slide 15 text
AMD Dependencies
• Modules are referred to by their name, which
comes from the URL:
store.biz/static/frontend/Magento/luma/pl_PL/Magent
Slide 16
Slide 16 text
AMD Dependencies
PL/Magento_Checkout/js/view/sidebar.js
• Modules are referred to by their name, which
comes from the URL:
Slide 17
Slide 17 text
AMD Dependencies
• Modules are referred to by their name, which
comes from the URL:
PL/Magento_Checkout/js/view/sidebar
Slide 18
Slide 18 text
AMD Dependencies
• Can also be configured via a mapping
• requirejs-config.js
• As a sibling to the web directory
• Standard RequireJS Config
• Merged by Magento\Framework\Requirejs
JavaScript Component
• Basic unit of functionality in Magento 2
• Built on top of AMD, loaded by RequireJS
• Gives us The Way to get JavaScript into a page
• Comes in two parts: Definition, and Declaration
Slide 22
Slide 22 text
JS Component Definition
• A normal AMD module that returns a function.
• Function takes parameters of a configuration
object, and an HTML element.
Slide 23
Slide 23 text
JS Component Definition
define([], function addClass() {
function main (config, el) {
el.classList.add(
config.className);
}
return main;
});
Slide 24
Slide 24 text
JS Component Declaration
• JavaScript is included in the template, not the
layout XML
• Upshot: JavaScript is only included when it needs
to be
• Specially formatted JSON, that is picked up by
Magento
JS Component Definition
define([], function addClass() {
function main (config, el) {
el.classList.add(
config.className);
}
return main;
});
Slide 30
Slide 30 text
JS Components
• JS Components will only load once, but may be run
many times.
• Convention comes from jQuery UI: All jQuery UI
Widgets are valid JS Components.
• To run some general JavaScript, use * as the
element selector.
Slide 31
Slide 31 text
UI Apps
Slide 32
Slide 32 text
UI App
• A UI App (defined in Magento_Ui) is a JavaScript
Component.
• Renders a tree of uiComponents into a dynamic
web app.
• uiComponents ≠ UI Components
Slide 33
Slide 33 text
UI Components?
• UI Components are UI Apps under the hood.
• The checkout is not a UI Component, it is a UI
App.
• Configured by the layout, not a ui_component file.
• UI Components are out of scope.
Slide 34
Slide 34 text
uiComponent
• AMD Module.
• A view model, or "block" in Magento language.
• Extend from this root component to create your
own.
• Define the public API for a template.
Slide 35
Slide 35 text
When to Use
• For rendering private data.
• Serves whole page from Varnish.
• Only loads private data through API.
Templating
• Your view-model is linked to a template.
• Templates are parsed by Knockout
• Knockout uses a special binding syntax to make
views dynamic.
Slide 41
Slide 41 text
Binding
Click Me!
We are visible!
Slide 42
Slide 42 text
Observables
• Your view model will receive notifications about
state changes.
• Your view needs to respond to these.
• Knockout Observables are data objects you can
"subscribe" to, and be notified of changes.
Component Configuration
• uiComponents are configured in the layout XML as
a constructor argument.
• Syntax is like DI XML, with deeply nested arrays.
• Magento\Checkout\Block\Onepage resolves this
array into JSON.
Slide 47
Slide 47 text
XML Configuration
...
Slide 48
Slide 48 text
XML Configuration
My_Module/js/view/component
Slide 49
Slide 49 text
XML Configuration
My_Module/js/view/component
Slide 50
Slide 50 text
XML Configuration
My_Module/js/view/component
Slide 51
Slide 51 text
XML Configuration
My_Module/js/view/component
Slide 52
Slide 52 text
XML Configuration
...
myComponent
// It begins all over again.
Slide 53
Slide 53 text
XML Configuration
...
myComponent
// It begins all over again.
Slide 54
Slide 54 text
Rendering Children
• An app is a tree of UI Components.
• Get a child by calling getRegion(name).
• getRegion always returns an array.
• Get all children with this.regions.
Slide 55
Slide 55 text
Rendering a child
Slide 56
Slide 56 text
Component Registry
• A component "class" is a function that returns a
constructor, not the component itself.
• You cannot load a component as a dependency
• Use the registry to get a component.
• Registry key is the component's name with all
parent component's names. Not displayArea
Slide 57
Slide 57 text
Component Registry
let shippingStep = registry.get(
'checkout.steps.shipping-step'
); // may be undefined
Slide 58
Slide 58 text
Component Registry
• All JavaScript is loaded and executed
asynchronously.
• You cannot depend on components being loaded.
• Magento has an answer here...