Javascript - Asynchronous Module Definition (AMD)

About

The AMD 1) 2) specifies a mechanism for defining modules such that:

  • the module
  • and its dependencies

can be specified and loaded asynchronously. 3)

ie Both the module and dependencies can be asynchronously loaded.

API: Import / Export

The import and export functionality of a module in an AMD specification/environment are split between two functions:

  • for the export: the define function: to import module dependencies and export your module public api
  • for the import: the require function: to import module dependencies and use them

An AMD loader implementation will define them as two global variables require and define

Define

The define function accepts as parameters:

  • an array of module ids (that specify the dependency)
  • and a factory function that returns values in order to export (made public) any JavaScript type (function, constructor, object)

AMD defines a single function define that is available as a free variable or a global variable. 4)

define(
  module_id /*optional if not present, the module is anonymous. */, 
  ['my-dependency-1', 'my-dependency-2'], /*optional*/, 
  function(MyDependency1, MyDependency2) { /*function for instantiating the module or object*/
     return function() {};
});

Example 5):

define(["./cart", "./inventory"], function(cart, inventory) {
        //return an object to define the "my/shirt" module.
        return {
            color: "blue",
            size: "large",
            addToCart: function() {
                inventory.decrement(this);
                cart.add(this);
            }
        }
    }
);

Require

  • AMD module require 6)
require(['myModule'], function ( myModule ) {
  // ...
  // AMD module use
  myModule.myFunction('Arg1');
  // ...
});

Implementation (AMD Loader)

This section regroups the module loader implementation based on AMD

RequireJs

requirejs implements and delivers an AMD environment where you can use the define and require function.

Proof:

<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js" integrity="sha512-c3Nl8+7g4LMSTdrm621y7kf9v3SDPnhxLNhcjFJbKECVnmZHTdo+IRO05sNLTH/D3vA6u1X32ehoLC7WFVdheg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  • Make your browser environment AMD capable (If the environment has the define function and the amd property this is an amd environment)
console.log("Is this an AMD environment ? "+(typeof define === 'function' && "amd" in define))
  • Output:

Dojo

Other Loader

Browser Alone

Note the browser alone is not an AMD environment

console.log("Is this an AMD environment ? "+(typeof define === 'function' && "amd" in define))

UMD and AMD

Because umd is wrapper around amd, you can use any umd module in a AMD environment

Package

AMD supports the notion of packages 7). They are simply collections of modules.

Example with the dojo package configuration 8)

var amdConfig = {
  packages: [
        { name: "dojo", location: "//ajax.googleapis.com/ajax/libs/dojo/1.10.4/" },
        { name: "dijit", location: "lib/dijit" },
        { name: "dojox", location: "lib/dojox" }
  ]
}

A package manager can be used see CommonJS Package Manager.

Library support

Tools (Optimizer)

r.js

r.js 9) is a single script that has two major functions:

  • Run AMD-based projects in Node and Nashorn, Rhino and xpcshell.
  • Includes the RequireJS Optimizer that combines scripts for optimal browser delivery.

It is part of the RequireJS project


Powered by ComboStrap