Relation between CommonJS, AMD and RequireJS?
我对CommonJS、AMD和RequireJS仍然很困惑。即使读了很多书。
我知道CommonJS(以前叫ServerJS)是一个组,用于在浏览器外部使用该语言时定义一些JavaScript规范(即模块)。CommonJS模块规范有一些实现,比如node.js或ringojs,对吧?
CommonJS、异步模块定义(AMD)和RequireJS之间的关系是什么?Requirej是CommonJS模块定义的实现吗?如果是,那么AMD是什么?
RequireJS实现AMDAPI(源代码)。
CommonJS是一种在
1 2 3 4 5 6 | // 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指定您需要具有一个用于获取依赖项的
CommonJS的设计并不是特别考虑浏览器,因此它不适合浏览器环境(我真的没有这个来源——它在任何地方都这么说,包括RequireJS站点)。显然,这与异步加载等有关。
另一方面,RequireJS实现了AMD,这是为适应浏览器环境(源代码)而设计的。显然,AMD从CommonJS传输格式的衍生产品开始,发展成为自己的模块定义API。因此两者之间有相似之处。AMD中的新功能是
1 2 3 4 | define('module/id/string', ['module', 'dependency', 'array'], function(module, factory function) { return ModuleContents; }); |
因此,CommonJS和AMD是具有不同实现的JavaScript模块定义API,但它们都来自相同的起源。
- AMD更适合浏览器,因为它支持模块依赖项的异步加载。
- RequireJS是AMD的一个实现,同时试图保持CommonJS的精神(主要在模块标识符中)。
更让人困惑的是,RequireJS虽然是一个AMD实现,但它提供了一个CommonJS包装器,这样就可以直接导入CommonJS模块来与RequireJS一起使用。
1 2 3 4 | define(function(require, exports, module) { var someModule = require('someModule'); // in the vein of node exports.doSomethingElse = function() { return someModule.doSomething() +"bar"; }; }); |
希望这有助于澄清问题!
CommonJS不仅仅如此,它是一个为JavaScript定义公共API和生态系统的项目。通用JS的一部分是模块规范。node.js和ringojs是服务器端的javascript运行时,是的,它们都基于commonjs模块规范实现模块。
AMD(异步模块定义)是模块的另一个规范。RequireJS可能是AMD最流行的实现。与CommonJS的一个主要区别是AMD指定异步加载模块——这意味着模块是并行加载的,而不是通过等待加载完成来阻止执行。
因此,AMD通常更多地用于客户端(在浏览器中)的JavaScript开发,而CommonJS模块通常用于服务器端。但是,您可以在任意一个环境中使用任意一个模块规范—例如,RequireJS提供了在node.js中运行的指导,browserify是一个可以在浏览器中运行的通用JS模块实现。
简短的回答是:
CommonJS和AMD是有关如何在JavaScript应用程序中声明模块及其依赖项的规范(或格式)。
RequireJS是一个与AMD兼容的脚本加载程序库,CurlJS是另一个例子。
符合CommonJS:摘自艾迪·奥斯马尼的书。
1 2 3 4 5 6 7 8 9 10 | // 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 | // 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 } }); |
模块可用于其他地方:
1 2 3 | require(["package/myModule"], function(myModule) { myModule.foobar(); }); |
一些背景:
实际上,CommonJS不仅仅是一个API声明,而且只是其中的一部分。AMD最初是作为CommonJS列表中模块格式的规范草案开始的,但是还没有达成完全一致意见,格式的进一步开发转移到了AMDJS集团。关于哪种格式更好的争论表明,CommonJS试图涵盖更广泛的关注点,考虑到其同步性,它更适合服务器端开发,考虑到其异步性,以及其根源在Dojo的模块声明中,AMD更适合客户端(浏览器)开发。关于实施。
资料来源:- 要求-为什么是AMD?
- addy osmani-学习javascript设计模式-现代模块化javascript设计模式
引用
AMD:
- 一个浏览器优先方法
- 选择异步行为并简化向后兼容性
- 它没有任何文件I/O的概念。
- 它支持对象、函数、构造函数、字符串、JSON和许多其他类型的模块。
CommonJS:
- 一个服务器优先方法
- 假设同步行为
- 涵盖更广泛的关注点,如I/O、文件系统、承诺等。
- 支持未封装的模块,它可以感觉更接近es.next/harmony规范,从而释放了
AMD 强制使用的define()包装器。 - 仅支持对象作为模块。
将javascript程序模块化组织成多个文件并从
但Javascript并没有提供这个功能。即使是现在最新的浏览器版本的Chrome和FF也不例外。
But, is there any keyword in JavaScript to call another JavaScript module?
对于许多人来说,这个问题可能是世界彻底崩溃,因为答案是否定的。
在ES5(2009年发布)中,javascript没有像import、include或require这样的关键字。
ES6保存了建议导入关键字(https://developer.mozilla.org/en/docs/web/javascript/reference/statements/import)的日期(2015年发布),但没有浏览器实现这一点。
如果您使用Babel 6.18.0并仅使用ES2015选项
1 | import myDefault from"my-module"; |
你会再次得到
1 2 3 4 | "use strict"; var _myModule = require("my-module"); var _myModule2 = _interopRequireDefault(_myModule); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } |
这是因为
因为在javascript中,函数是表示模块的唯一包装器。
I'm a lot confused about CommonJS and AMD?
CommonJS和AMD都只是两种不同的技术,如何克服JavaScript的"缺陷"来智能加载模块。