AMD modules and RequireJS

Define AMD and async load with RequireJS

Asynchronous Module Definition (AMD)

This API allows to define:

  • modules
  • dependencies

Fast load, improves performance to use/debug.

API specifications

  • Function define()
    Registers a module in the loader:

    1
    define(id?, dependencies?, callback);
  • id: identifier.

    • Optional, usally not included.
    • Should be top level or an absolute id (relative ids are not allowed).
  • dependencies: array of module ids, which are required by the modile we are defining.

    • Its values are solved before executing the callback, and should be apssed via args in the same order as the array.
    • If it is not included, it will use the “require”, “exports” and “module” dependencies.
    • If it is included, the loader should not scan the callback to solve ten dependencies.
  • callback: function to execute to instance the module or an object.

    • If it is a function, it will be executed once.
    • If it is an Object, it should be asigned as value to export from the module.
    • If the callback returns a value, it should be assigned as a value exported from the module.

Property define.amd

  • Avoids conflict with Javascript define()
  • It is not part of the AMD API
  • It can be used for other API implementations (or versions), due to convention

Call more than one module at once

  • Using multiple define calls can be done in a single script.
  • Order should not matter.
  • The loader is responsible of dealing with the dependencies that are not solved until the script is completely loaded to avoid unnecessary requests.
    1
    2
    3
    4
    5
    6
    7
    8
    //anon module which return a literal object
    define(["alpha"], function (alpha) {
    return {
    verb: function(){
    return alpha.verb() + 2;
    }
    };
    });

❗Note: loaders should not add more methods or properties to the define function.

More info on:

RequireJS

RequireJS is the async loader we have been talking about in the AMD section.

  • NodeJs adds a loader which uses the CommonJS formatS, which doesn’t deal well with the browser.
  • Using RequireJS allows us using a single format for all the modules, server or client.
  • It can be configured for only client use.
  • The NodeJs adapter (r.js) for RequireJS will use the require implementation and search for paths in NodeJS
    if the module can’t be found its configuration: RequireJS will assume it is a module which uses config and modules type NodeJS.

Configuration

First we add the library to our project:

1
2
<script data-main="/pages/<%= distName %>/<%= version %>/js/config"
src="/pages/<%= distName %>/<%= version %>/js/vendor/require.js"></script>

By loading RequireJS, we get access to the “require” object. The data-main loads the input point for every dependency on our app (in this case it would be “config.js”, which also configures the “require” object). From here on, we should follow AMD patterns on our modules.
Example:

1
2
3
require(["jquery"], function($) {
$("#mydiv").html("Hello this is RequireJS talking");
});

More info on: