7.2. AMD and RequireJS

Warning

You are looking at documentation for an older release. Not what you want? See the current release documentation.

What is AMD?

The module pattern gives you a way to create your namespace to protect private things inside. What if your module depends on other libraries, and the libraries use each other in chain? What if different versions of a library are used by other applications in the same page? Is there a way to always have the right libraries loaded in the right order?

The answer is to modularize the libraries themselves. The AMD (Asynchronous Module Definition) standard defines the way that a library is loaded as a module - as opposite to a global object, and that module is available for only the other module that "requires" it.

How it works?

Let's say there are three companions in an AMD system: the library as a dependency, an AMD loader, and a consumer - the module that wishes to use the library. To avoid confusion, all are JavaScript. Here is how they work:

Next, you will learn it via examples with RequireJS and jQuery.

RequireJS

RequireJS is an AMD loader. To download it, check out Get RequireJS page.

As said, you do not declare a library directly in script tags, but register it to the loader instead. How registration is done depends on the loader. Here you write an example of RequireJS in which you use jQuery and one module of your own.

Note

The code sample can be found at eXo Samples repository.

It is built up from the previous example. Now "count" function is wrapped into an AMD module, called util. The consumer is my.js that contains onclick function. The html file simply gives a button to test the function.

Look at the html file first:


<!DOCTYPE html>
<meta charset="utf-8" />
<html>
<head>
<script data-main="js/my" src="js/require.js"></script>
</head>
<body>
    <p>You've clicked <span id="result">0</span> times.</p>
    <button onclick="myClick();">Click me</button>
</body>
</html>

So here it is RequireJS that is loaded in script tag. my.js is not loaded traditionally, instead it is the data-main source of RequireJS. my.js registers the dependencies by calling require.config({...}):

require.config({
	baseUrl: "js",
	paths: {
		jquery: "jquery-3.2.1",
		util: "util"
	}
});

This is a conventional configuration of RequireJS. You may omit the configuration for "util", because RequireJS can auto-load scripts that are located right under the baseUrl directory. In that case the module name will be the file name without extension.

The util.js module is re-written from the "count" example. You define an anonymous AMD module:

define(function(){
	var counter = 0;
	var count = function(){
		if (counter > 10) {
			alert("Stop! You're too excited!");
		}
		return (++counter);
	}
	return {
		count: count
	};
});

JQuery accompanies AMD specification, though it also produces global variables. The following code is much more than a define() function, because it tries detecting if there is an AMD loader.

if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
	define( "jquery", [], function () { return jQuery; } );
}

The last gap is how the consumer uses the libararies. In my.js:

function myClick(){
	require(["util", "jquery"], function(util, $){
		$("#result").text(util.count());
	});
}

Next, you will learn how to use non-AMD libraries with RequireJS.

References

This tutorial helps you understand the gist of JavaScript modularity, by walking through the patterns from basic to advance. It does not cover everything, indeed it avoids explaining a lot of things. So do not limit yourself. Go ahead and read other references.

At this point you should read:

Copyright ©. All rights reserved. eXo Platform SAS
blog comments powered byDisqus