我仍然对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是什么?
当前回答
引用
AMD:
一种浏览器优先的方法 选择异步行为和简化向后兼容性 它没有任何文件I/O的概念。 它支持对象、函数、构造函数、字符串、JSON和许多其他类型的模块。
CommonJS:
一种服务器优先的方法 假设同步行为 涵盖更广泛的问题集,如I/O,文件系统,承诺等。 支持未包装模块,感觉更接近ES。next/Harmony规范,将你从AMD强制的define()包装器中解放出来。 只支持对象作为模块。
其他回答
将JavaScript程序模块组织成几个文件并从主js模块调用子模块是很正常的。
问题是JavaScript没有提供这个。即使在最新版本的Chrome和FF浏览器中也没有。
但是,JavaScript中是否有关键字可以调用另一个JavaScript模块呢?
对许多人来说,这个问题可能是世界的彻底崩溃,因为答案是否定的。
在ES5(2009年发布)中,JavaScript没有import、include或require这样的关键字。
ES6挽救了局面(2015年发布)提出了import关键字(https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/import),现在所有现代浏览器都支持它。
如果您使用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的“缺陷”来智能加载模块。
AMD
在JavaScript中引入将JavaScript项目扩展到多个文件 主要用于基于浏览器的应用程序和库 流行的实现是RequireJS, Dojo Toolkit
CommonJS:
它是处理大项目中大量功能、文件和模块的规范 ServerJS的初始名称是Mozilla在2009年1月引入的 2009年8月更名为CommonJS,以显示api更广泛的适用性 最初的实现是服务器,nodejs,基于桌面的库
例子
upper.js文件
exports.uppercase = str => str.toUpperCase()
main.js文件
const uppercaseModule = require('uppercase.js')
uppercaseModule.uppercase('test')
总结
AMD——最古老的模块系统之一,最初由require.js库实现。 CommonJS -为Node.js服务器创建的模块系统。 UMD -一个多模块系统,建议作为一个通用系统,兼容AMD和CommonJS。
资源:
https://exploringjs.com/es6/ch_modules.html#sec_modules-in-javascript 维基百科
CommonJS不仅仅是这样——它是一个为JavaScript定义通用API和生态系统的项目。CommonJS的一部分是Module规范。Node.js和RingoJS是服务器端JavaScript运行时,是的,它们都实现了基于CommonJS模块规范的模块。
AMD(异步模块定义)是另一种模块规范。RequireJS可能是AMD最流行的实现。与CommonJS的一个主要区别是AMD指定模块是异步加载的——这意味着模块是并行加载的,而不是通过等待加载完成来阻塞执行。
因此,AMD通常更多地用于客户端(浏览器内)JavaScript开发,而CommonJS模块通常用于服务器端。然而,你可以在任何一个环境中使用任何一个模块规范——例如,RequireJS提供了在Node.js中运行的指导,而browserify是一个可以在浏览器中运行的CommonJS模块实现。
引用
AMD:
一种浏览器优先的方法 选择异步行为和简化向后兼容性 它没有任何文件I/O的概念。 它支持对象、函数、构造函数、字符串、JSON和许多其他类型的模块。
CommonJS:
一种服务器优先的方法 假设同步行为 涵盖更广泛的问题集,如I/O,文件系统,承诺等。 支持未包装模块,感觉更接近ES。next/Harmony规范,将你从AMD强制的define()包装器中解放出来。 只支持对象作为模块。
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传输格式的衍生品,后来发展成了自己的模块定义API。因此两者有相似之处。AMD的新特性是define()函数,它允许模块在加载之前声明它的依赖项。例如,定义可以是:
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中使用。
define(function(require, exports, module) {
var someModule = require('someModule'); // in the vein of node
exports.doSomethingElse = function() { return someModule.doSomething() + "bar"; };
});