CommonJS,AMD和RequireJS之间的关系?

我仍然对CommonJS,AMD和RequireJS感到困惑。 即使阅读了很多。

我知道CommonJS(以前称为ServerJS)是一组用于在浏览器外部使用该语言时定义一些JavaScript规范(即模块)的组。 CommonJS模块规范有一些像Node.js或RingoJS的实现,对吧?

CommonJS,异步模块定义(AMD)和RequireJS之间有什么关系? RequireJS是否实现了CommonJS模块定义? 如果是,那么AMD是什么?


RequireJS实现AMD API(源代码)。

CommonJS是一种定义模块的方法,它在定义模块内容的exports对象的帮助下进行。 简而言之,一个CommonJS实现可能像这样工作:

// 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"; };

基本上,CommonJS指定你需要有一个require()函数来获取依赖关系,一个exports变量来导出模块内容和一个模块标识符(它描述了与这个模块相关的问题模块的位置)依赖关系(来源)。 CommonJS有各种实现,包括Node.js ,你提到过。

CommonJS并没有特别考虑浏览器的设计,所以它不适合浏览器环境(我真的没有这方面的资源 - 它只是说到处都是,包括RequireJS网站。)显然,这有一些使用异步加载等。

另一方面,RequireJS实现了AMD,该设计适合浏览器环境(源代码)。 显然,AMD最初是从CommonJS Transport格式衍生出来的,并演变成了自己的模块定义API。 因此两者之间的相似之处。 AMD的新功能是define()函数,它允许模块在加载之前声明它的依赖关系。 例如,定义可以是:

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

因此,CommonJS和AMD是JavaScript模块定义API,具有不同的实现,但都来自相同的起源。

  • AMD更适合浏览器,因为它支持异步加载模块依赖。
  • RequireJSAMD的一个实现,同时试图保持CommonJS的精神(主要是模块标识符)。
  • 为了更加迷惑你,RequireJS在作为AMD实现时提供了一个CommonJS包装器,所以CommonJS模块几乎可以直接导入,以便与RequireJS一起使用。

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

    我希望这有助于澄清事情!


    CommonJS不仅仅是这个 - 它是一个为JavaScript定义公共API和生态系统的项目。 CommonJS的一部分是模块规范。 Node.js和RingoJS是服务器端JavaScript运行时,是的,它们都实现了基于CommonJS模块规范的模块。

    AMD(异步模块定义)是另一个模块规范。 RequireJS可能是AMD最受欢迎的实现。 CommonJS的一个主要区别是AMD指定模块异步加载 - 这意味着模块并行加载,而不是通过等待加载完成来阻止执行。

    由于这个原因,AMD通常更多地用于客户端(浏览器内)JavaScript开发,而CommonJS模块通常用于服务器端。 但是,您可以在任一环境中使用模块规范 - 例如,RequireJS提供在Node.js中运行的指导,而browserify是可以在浏览器中运行的CommonJS模块实现。


    简短的答案是:

    CommonJSAMD是关于如何在javascript应用程序中声明模块及其依赖关系的规范(或格式)。

    RequireJS是一个符合AMD标准的脚本加载器库,curljs是另一个例子。

    CommonJS兼容:

    来自Addy Osmani的书。

    // 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兼容:

    // 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
        }
    });
    

    模块可以在其他地方使用:

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

    一些背景:

    实际上,CommonJS不仅仅是一个API声明,它只是其中的一部分。 AMD最初是作为CommonJS列表中模块格式的草案规范开始的,但尚未达成完全共识,并将格式的进一步发展转移到了amdjs组。 围绕哪种格式更好的说法表明,CommonJS试图覆盖更广泛的关注点,并且考虑到其同步特性,它更适合于服务器端开发,并且鉴于其异步性质以及AMD的特性,AMD更适合客户端(浏览器)开发。事实上它源于Dojo的模块声明实现。

    资料来源:

  • RequireJS - 为什么选择AMD?
  • Addy Osmani - 学习JavaScript设计模式 - 现代模块化JavaScript设计模式
  • 链接地址: http://www.djcxy.com/p/70409.html

    上一篇: Relation between CommonJS, AMD and RequireJS?

    下一篇: Loading Backbone and Underscore using RequireJS