即使阅读了很多,我仍然对CommonJS,AMD和RequireJS感到非常困惑。
我知道CommonJS(以前称为ServerJS)是用于在浏览器之外使用该语言时定义一些JavaScript规范(即模块)的组。CommonJS模块规范具有一些实现,例如Node.js或RingoJS,对吗?
CommonJS,异步模块定义(AMD)和RequireJS之间是什么关系?
是RequireJS的的实现CommonJS的模块定义?如果是,那么AMD是什么?
即使阅读了很多,我仍然对CommonJS,AMD和RequireJS感到非常困惑。
我知道CommonJS(以前称为ServerJS)是用于在浏览器之外使用该语言时定义一些JavaScript规范(即模块)的组。CommonJS模块规范具有一些实现,例如Node.js或RingoJS,对吗?
CommonJS,异步模块定义(AMD)和RequireJS之间是什么关系?
是RequireJS的的实现CommonJS的模块定义?如果是,那么AMD是什么?
Answers:
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旨在适应浏览器环境(source)。显然,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 Module规范实现模块。
AMD(异步模块定义)是另一种模块规范。RequireJS可能是AMD最受欢迎的实现。与CommonJS的主要区别在于,AMD指定模块是异步加载的-这意味着模块是并行加载的,而不是通过等待加载完成来阻止执行。
因此,AMD通常更多地用于客户端(浏览器)JavaScript开发中,而CommonJS模块通常用于服务器端。但是,您可以在任何环境中使用任何一种模块规范-例如,RequireJS提供了在Node.js中运行的说明,而browserify是可以在浏览器中运行的CommonJS Module实现。
CommonJS和 AMD是有关应如何在javascript应用程序中声明模块及其依赖关系的规范(或格式)。
RequireJS是一个符合AMD要求的脚本加载程序库,另一个示例是 curljs。
// 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;
// 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更适合于客户端(浏览器)开发。它起源于Dojo的模块声明实现这一事实。
AMD compliant
实际上是RequireJS,对吗?
AMD:
CommonJS:
AMD
强制执行的define()包装器。将JavaScript程序模块化组织为多个文件并从中调用是很正常child-modules
的main js module
。
问题是JavaScript不提供此功能。直到今天,最新版的Chrome和FF浏览器都没有。
但是,JavaScript中是否有关键字可以调用另一个JavaScript模块?
这个问题可能是世界上的许多完全崩溃,因为答案是没有。
在ES5(于2009年发布)中,JavaScript没有诸如import,include或require之类的关键字。
ES6节省了建议使用import关键字( https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/import)的日期(于2015年发布),但是没有浏览器实现此目的。
如果您使用Babel 6.18.0并仅通过ES2015选项进行转换
import myDefault from "my-module";
你会require
再次得到。
"use strict";
var _myModule = require("my-module");
var _myModule2 = _interopRequireDefault(_myModule);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
这是因为require
意味着将从Node.js加载模块。Node.js将处理从系统级文件读取到将函数包装到模块中的所有内容。
因为在JavaScript中,函数是表示模块的唯一包装。
我对CommonJS和AMD感到困惑?
CommonJS和AMD都是仅两种不同的技术,可以克服JavaScript的“缺陷”以智能地加载模块。