Here is a little AMD 101.
AMD, by the way, stands for Asynchronous Module Definition, so saying "AMD
module" is a bit of a RAS syndrome, but everybody does it anyway.
First, let's define the problem.
Say you're developing a Web application with a fair amount of client side
functionality. Or, perhaps, a totally client side application.
When your Javascript code is more than "hello world", you may want to
split it into several components and, perhaps, multiple files (you know, just
for the sake of mental health).
Further, you may want to develop some of those components independently as a
library. Or, perhaps, you want to use a library that somebody else already
developed for you.
And then those libraries may want to use other libraries, and so on. You know,
very much the way you build other, non-Javascript applications.
But here is the problem: how do you know which Javascript files to include in your
page? Obviously, the libraries must have some way of specifying which files
they need, and these specifications must propagate from the deepest layers of
the libraries all the way to the top. This problem can be solved with some
trickery, but...
But that's only half of the problem. The other half - correct order. How do you
ensure that the browser doesn't execute a particular script until all its
dependencies are loaded? And with the internet being asynchronous and all, the
order of loading can be anything.
So you must create sort of a dependency graph of all the libraries, and only
then go about loading them in the correct order.
A piece of software that does this graph thing is called an "AMD
loader".
There are many of those available. The one I'm using is
called RequireJS. But they all, thank the great open source community, have the
exact same standard API.
Here is how it works.
The AMD loader provides two functions: "define" and
"require".
The "define" function defines a module. Every time you call it, the
AMD loader knows: "aha, here is another module".
The first argument of define() is an array that contains names of modules that
the module being defined depends upon. The second argument is a function that
gets called once all the dependencies are loaded, and the arguments passed to
that function will be the values exported from those dependencies, in the same
order.
The return value of that function is the value that this module wants to
export.
define ( ["jQuery"], function ($) {
// the module code goes here
return "my exported value";
});
The require() method works almost exactly the same, except the function doesn't
return anything. The require() call is the "top level" of the module
hierarchy.
No comments:
Post a Comment