Javascript CommonJS、AMD和RequireJS之间的关系?

Javascript CommonJS、AMD和RequireJS之间的关系?,javascript,module,requirejs,amd,commonjs,Javascript,Module,Requirejs,Amd,Commonjs,我仍然对CommonJS、AMD和RequireJS感到非常困惑,即使读了很多书 我知道CommonJS(以前的ServerJS)是一个组,用于在浏览器之外使用语言时定义一些JavaScript规范(即模块)CommonJS模块规范有一些实现,比如Node.js或RingoJS,对吗 CommonJS、异步模块定义(AMD)和RequireJS之间有什么关系 RequireJS是CommonJS模块定义的实现吗?如果是,那么什么是AMD 不仅如此,它还是一个为JavaScript定义通用API和

我仍然对CommonJS、AMDRequireJS感到非常困惑,即使读了很多书

我知道CommonJS(以前的ServerJS)是一个组,用于在浏览器之外使用语言时定义一些JavaScript规范(即模块)CommonJS模块规范有一些实现,比如Node.jsRingoJS,对吗

CommonJS异步模块定义(AMD)和RequireJS之间有什么关系

RequireJSCommonJS模块定义的实现吗?如果是,那么什么是AMD

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

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


因此,AMD通常更多地用于客户端(在浏览器中)JavaScript开发,而CommonJS模块通常用于服务器端。但是,您可以在任一环境中使用任一模块规范-例如,RequireJS提供并且是一个可以在浏览器中运行的通用JS模块实现。

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()
函数来获取依赖项,一个
导出
变量来导出模块内容,以及一个模块标识符(描述与此模块相关的模块的位置),用于要求依赖项()。CommonJS有多种实现,包括您提到的Node.js

CommonJS并不是专门为浏览器设计的,所以它不太适合浏览器环境(我真的没有这方面的源代码——它只是到处都这么说,包括)显然,这与异步加载有关,等等

另一方面,RequireJS实现AMD,AMD是为适应浏览器环境而设计的()。显然,AMD最初是CommonJS传输格式的衍生产品,后来演变成了自己的模块定义API。因此,两者之间存在相似之处。AMD中的新功能是
define()
函数,该函数允许模块在加载之前声明其依赖项。例如,定义可以是:

define('module/id/string', ['module', 'dependency', 'array'], 
function(module, factory function) {
  return ModuleContents;  
});
因此,CommonJS和AMD是具有不同实现的JavaScript模块定义API,但它们来自相同的来源

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

define(function(require, exports, module) {
  var someModule = require('someModule'); // in the vein of node    
  exports.doSomethingElse = function() { return someModule.doSomething() + "bar"; };
});
我希望这有助于澄清问题

简单的回答是: 是关于如何在javascript应用程序中声明模块及其依赖项的规范(或格式)

是一个与AMD兼容的脚本加载程序库,这是另一个例子

CommonJS兼容: 摘自

符合AMD标准: 在其他地方,该模块可用于:

require(["package/myModule"], function(myModule) {
    myModule.foobar();
});
一些背景: 事实上,它不仅仅是一个API声明,而且只是其中的一部分。AMD最初是作为CommonJS列表中模块格式的规范草案,但没有达成完全一致意见,该格式的进一步开发转移到了通用JS列表中。围绕哪种格式更好的争论表明CommonJS试图涵盖更广泛的关注点,鉴于其同步性,它更适合服务器端开发,AMD更适合客户端(浏览器)考虑到它的异步性质以及它植根于Dojo的模块声明实现这一事实,进行开发

资料来源:

AMD

  • 一浏览器优先的方法
  • 选择异步行为和简化的向后兼容性
  • 它没有任何文件I/O的概念
  • 它支持对象、函数、构造函数、字符串、JSON和许多其他类型的模块
CommonJS

  • 一个服务器优先的方法
  • 假设同步行为
  • 涵盖更广泛的关注点,如I/O、文件系统、承诺等
  • 支持未包装的模块,它可以感觉更接近于规范,从而使您摆脱了
    AMD
    强制实施的define()包装
  • 仅支持对象作为模块

将JavaScript程序模块组织到多个文件中并从
主js模块调用
子模块
是很正常的

问题是JavaScript没有提供这一点。甚至在最新版本的Chrome和FF浏览器中也没有

但是,JavaS中有任何关键字吗
// 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();
});
import myDefault from "my-module";
"use strict";
var _myModule = require("my-module");
var _myModule2 = _interopRequireDefault(_myModule);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
exports.uppercase = str => str.toUpperCase()
const uppercaseModule = require('uppercase.js')
uppercaseModule.uppercase('test')