Relation between CommonJS, AMD and RequireJS?

I'm still very confused about CommonJS, AMD and RequireJS. Even after reading a lot.

I know that CommonJS (formerly ServerJS) is a group for defining some JavaScript specifications (ie modules) when the language is used outside the browser. CommonJS modules specification has some implementation like Node.js or RingoJS, right?

What's the relation between CommonJS, Asynchronous Module Definition (AMD) and RequireJS? Is RequireJS an implementation of CommonJS module definition? If yes, what's AMD then?


RequireJS implements the AMD API (source).

CommonJS is a way of defining modules with the help of an exports object, that defines the module contents. Simply put, a CommonJS implementation might work like this:

// someModule.js
exports.doSomething = function() { return "foo"; };

//otherModule.js
var someModule = require('someModule'); // in the vein of node    
exports.doSomethingElse = function() { return someModule.doSomething() + "bar"; };

Basically, CommonJS specifies that you need to have a require() function to fetch dependencies, an exports variable to export module contents and a module identifier (which describes the location of the module in question in relation to this module) that is used to require the dependencies (source). CommonJS has various implementations, including Node.js , which you mentioned.

CommonJS was not particularly designed with browsers in mind, so it doesn't fit in the browser environment very well (I really have no source for this--it just says so everywhere, including the RequireJS site.) Apparently, this has something to do with asynchronous loading, etc.

On the other hand, RequireJS implements AMD, which is designed to suit the browser environment (source). Apparently, AMD started as a spinoff of the CommonJS Transport format and evolved into its own module definition API. Hence the similarities between the two. The new feature in AMD is the define() function that allows the module to declare its dependencies before being loaded. For example, the definition could be:

define('module/id/string', ['module', 'dependency', 'array'], 
function(module, factory function) {
  return ModuleContents;  
});

So, CommonJS and AMD are JavaScript module definition APIs that have different implementations, but both come from the same origins.

  • AMD is more suited for the browser, because it supports asynchronous loading of module dependencies.
  • RequireJS is an implementation of AMD , while at the same time trying to keep the spirit of CommonJS (mainly in the module identifiers).
  • To confuse you even more, RequireJS, while being an AMD implementation, offers a CommonJS wrapper so CommonJS modules can almost directly be imported for use with RequireJS.

    define(function(require, exports, module) {
      var someModule = require('someModule'); // in the vein of node    
      exports.doSomethingElse = function() { return someModule.doSomething() + "bar"; };
    });
    

    I hope this helps to clarify things!


    CommonJS is more than that - it's a project to define a common API and ecosystem for JavaScript. One part of CommonJS is the Module specification. Node.js and RingoJS are server-side JavaScript runtimes, and yes, both of them implement modules based on the CommonJS Module spec.

    AMD (Asynchronous Module Definition) is another specification for modules. RequireJS is probably the most popular implementation of AMD. One major difference from CommonJS is that AMD specifies that modules are loaded asynchronously - that means modules are loaded in parallel, as opposed to blocking the execution by waiting for a load to finish.

    AMD is generally more used in client-side (in-browser) JavaScript development due to this, and CommonJS Modules are generally used server-side. However, you can use either module spec in either environment - for example, RequireJS offers directions for running in Node.js and browserify is a CommonJS Module implementation that can run in the browser.


    The short answer would be:

    CommonJS and AMD are specifications (or formats) on how modules and their dependencies should be declared in javascript applications.

    RequireJS is a script loader library that is AMD compliant, curljs being another example.

    CommonJS compliant:

    Taken from Addy Osmani's book.

    // package/lib is a dependency we require
    var lib = require( "package/lib" );
    
    // behavior for our module
    function foo(){
        lib.log( "hello world!" );
    }
    
    // export (expose) foo to other modules as foobar
    exports.foobar = foo;
    

    AMD compliant:

    // package/lib is a dependency we require
    define(["package/lib"], function (lib) {
    
        // behavior for our module
        function foo() {
            lib.log( "hello world!" );
        }
    
        // export (expose) foo to other modules as foobar
        return {
            foobar: foo
        }
    });
    

    Somewhere else the module can be used with:

    require(["package/myModule"], function(myModule) {
        myModule.foobar();
    });
    

    Some background:

    Actually, CommonJS is much more than an API declaration and only a part of it deals with that. AMD started as a draft specification for the module format on the CommonJS list, but full consensus wasn't reached and further development of the format moved to the amdjs group. Arguments around which format is better state that CommonJS attempts to cover a broader set of concerns and that it's better suited for server side development given its synchronous nature, and that AMD is better suited for client side (browser) development given its asynchronous nature and the fact that it has its roots in Dojo's module declaration implementation.

    Sources:

  • RequireJS - Why AMD?
  • Addy Osmani - Learning JavaScript Design Patterns - Modern Modular JavaScript Design Patterns
  • 链接地址: http://www.djcxy.com/p/70410.html

    上一篇: 主干和AMD依赖性定义,参数与变量

    下一篇: CommonJS,AMD和RequireJS之间的关系?