Consider the first snippet, which is in the CommonJS style:
var $ = require('jquery');
var _ = require('underscore');
var BackBone = require('backbone');
These calls are synchronous calls: when require
returns, it returns the module you requested. CommonJS require
calls are synchronous. There is a proposal for supporting asynchronous forms of require
but as far as I can tell it has not progressed beyond the proposal level. Node.js used to have require.async
which has been removed. There's a package that implements it though. Using this package looks at lot like using AMD style modules.
Now, consider the second snippet, which is in the AMD style:
require(['jquery','underscore','backbone'],function ($, _, BackBone){
//code goes here
})
Since RequireJS implements the AMD type of module system, the above code works with RequireJS. This require
call is --- as suggested by the name Asynchronous Module Definition (AMD) --- asynchronous. You can't rely on the return value of require
to get a module value. You have to use a callback instead. The define
call works in a similar way but defines a module in addition to requiring modules.
Now, if you use RequireJS, it provides facilities that allow to use either style when you define modules so that you can define a module like this:
define(['jquery','underscore','backbone'],function ($, _, BackBone){
//code goes here
});
Or use something that looks more like the CommonJS idiom like this:
define(function (require) {
var $ = require('jquery');
var _ = require('underscore');
var BackBone = require('backbone');
//code goes here
});
It makes it really easy to convert a CommonJS style module to use with RequireJS: just wrap it with a define
call as above. There's a tool to help the conversion.
Behind the scenes, RequireJS reads the code of the callback in the 2nd form and creates a list of dependencies so that in the end it is interpreted like:
define(['require', 'jquery','underscore','backbone'], function (require) {
var $ = require('jquery');
var _ = require('underscore');
var BackBone = require('backbone');
//code goes here
})
It may be surprising (given that AMD is asynchronous) that the require
calls in the callback are synchronous. This is part of RequireJS's support for the CommonJS style. RequireJS supports a kind of synchronous require
call but with the following caveat: if the module is already defined before the call to the synchronous require
, then the synchronous require
returns the module's value, but otherwise it fails immediately. That is, it does not try to load a module. Because RequireJS interprets a module definition that uses the CommonJS style as I've shown above --- as if the dependencies were actually listed in the define
arguments --- then these modules are guaranteed to be loaded by the time the synchronous calls to require
are made.
Besides being able to use CommonJS modules in RequireJS (provided a wrapper is added), it is also possible to use modules designed for RequireJS in a CommonJS environment like Node.js. For instance, I've used node-amd-loader to load modules I've designed as AMD modules in Node.js.