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,具有不同的实现,但都来自相同的起源。
为了更加迷惑你,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模块实现。
简短的答案是:
CommonJS和AMD是关于如何在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的模块声明实现。