CommonJS,AMD和RequireJS之间的关系?

本文翻译自:Relation between CommonJS, AMD and RequireJS?

I'm still very confused about CommonJS, AMD and RequireJS. 我对CommonJS,AMD和RequireJS仍然很困惑。 Even after reading a lot. 即使阅读了很多。

I know that CommonJS (formerly ServerJS) is a group for defining some JavaScript specifications (ie modules) when the language is used outside the browser. 我知道CommonJS(以前称为ServerJS)是用于在浏览器之外使用该语言时定义一些JavaScript规范(即模块)的组。 CommonJS modules specification has some implementation like Node.js or RingoJS, right? CommonJS模块规范有一些实现,例如Node.js或RingoJS,对吗?

What's the relation between CommonJS, Asynchronous Module Definition (AMD) and RequireJS? CommonJS,异步模块定义(AMD)和RequireJS之间有什么关系? Is RequireJS an implementation of CommonJS module definition? RequireJS是CommonJS模块定义的实现吗? If yes, what's AMD then? 如果是,那么AMD是什么?


#1楼

参考:https://stackoom.com/question/17JzL/CommonJS-AMD和RequireJS之间的关系


#2楼

CommonJS is more than that - it's a project to define a common API and ecosystem for JavaScript. CommonJS不仅限于此-它是一个为JavaScript定义通用API和生态系统的项目。 One part of CommonJS is the Module specification. CommonJS的一部分是模块规范。 Node.js and RingoJS are server-side JavaScript runtimes, and yes, both of them implement modules based on the CommonJS Module spec. Node.js和RingoJS是服务器端JavaScript运行时,是的,它们都基于CommonJS Module规范实现模块。

AMD (Asynchronous Module Definition) is another specification for modules. AMD (异步模块定义)是另一种模块规范。 RequireJS is probably the most popular implementation of AMD. RequireJS可能是AMD最受欢迎的实现。 One major difference from CommonJS is that AMD specifies that modules are loaded asynchronously - that means modules are loaded in parallel, as opposed to blocking the execution by waiting for a load to finish. 与CommonJS的主要区别在于,AMD指定模块是异步加载的-这意味着模块是并行加载的,而不是通过等待加载完成来阻止执行。

AMD is generally more used in client-side (in-browser) JavaScript development due to this, and CommonJS Modules are generally used server-side. 因此,AMD通常更多地用于客户端(浏览器)JavaScript开发中,而CommonJS模块通常用于服务器端。 However, you can use either module spec in either environment - for example, RequireJS offers directions for running in Node.js and browserify is a CommonJS Module implementation that can run in the browser. 但是,您可以在任何环境中使用任何一个模块规范-例如,RequireJS提供了在Node.js中运行的说明,而browserify是可以在浏览器中运行的CommonJS Module实现。


#3楼

RequireJS implements the AMD API (source) . RequireJS实现AMD API (源) 。

CommonJS is a way of defining modules with the help of an exports object, that defines the module contents. CommonJS是在exports对象的帮助下定义模块的方法,该对象定义了模块的内容。 Simply put, a CommonJS implementation might work like this: 简而言之,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"; };

Basically, CommonJS specifies that you need to have a require() function to fetch dependencies, an exports variable to export module contents and a module identifier (which describes the location of the module in question in relation to this module) that is used to require the dependencies ( source ). 基本上,CommonJS指定您需要有一个require()函数来获取依赖项,一个exports变量以导出模块内容以及一个用来标识要求的模块标识符(描述了该模块相对于该模块的位置)依赖项( 源 )。 CommonJS has various implementations, including Node.js , which you mentioned. CommonJS具有各种实现,包括您提到的Node.js。

CommonJS was not particularly designed with browsers in mind, so it doesn't fit in the browser environment very well ( I really have no source for this--it just says so everywhere, including the RequireJS site. ) Apparently, this has something to do with asynchronous loading, etc. CommonJS并不是专门为浏览器而设计的,因此它不太适合浏览器环境( 我确实没有相关资源-它在包括RequireJS网站在内的所有地方都这么说。 )显然,这有一些不足之处异步加载等

On the other hand, RequireJS implements AMD, which is designed to suit the browser environment ( source ). 另一方面,RequireJS实现了AMD,该AMD旨在适应浏览器环境( source )。 Apparently, AMD started as a spinoff of the CommonJS Transport format and evolved into its own module definition API. 显然,AMD最初是从CommonJS Transport格式衍生出来的,后来演变为自己的模块定义API。 Hence the similarities between the two. 因此,两者之间的相似之处。 The new feature in AMD is the define() function that allows the module to declare its dependencies before being loaded. AMD中的新功能是define()函数,该函数允许模块在加载之前声明其依赖性。 For example, the definition could be: 例如,定义可以是:

define('module/id/string', ['module', 'dependency', 'array'], 
function(module, factory function) {
  return ModuleContents;  
});

So, CommonJS and AMD are JavaScript module definition APIs that have different implementations, but both come from the same origins. 因此,CommonJS和AMD是JavaScript模块定义API,它们具有不同的实现,但是它们来自相同的来源。

  • AMD is more suited for the browser, because it supports asynchronous loading of module dependencies. AMD更适合于浏览器,因为它支持异步加载模块依赖项。
  • RequireJS is an implementation of AMD , while at the same time trying to keep the spirit of CommonJS (mainly in the module identifiers). RequireJSAMD的实现,同时尝试保持CommonJS的精神(主要在模块标识符中)。

To confuse you even more, RequireJS, while being an AMD implementation, offers a CommonJS wrapper so CommonJS modules can almost directly be imported for use with RequireJS. 更令人困惑的是,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"; };
});

I hope this helps to clarify things! 我希望这有助于澄清问题!


#4楼

The short answer would be: 简短的答案是:

CommonJS and AMD are specifications (or formats) on how modules and their dependencies should be declared in javascript applications. CommonJSAMD是有关如何在javascript应用程序中声明模块及其依赖项的规范(或格式)。

RequireJS is a script loader library that is AMD compliant, curljs being another example. RequireJS是一个兼容AMD的脚本加载器库,另一个示例是curljs 。

CommonJS compliant: 符合CommonJS:

Taken from Addy Osmani's book . 摘自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 compliant: 符合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
    }
});

Somewhere else the module can be used with: 该模块可以在其他地方使用:

require(["package/myModule"], function(myModule) {
    myModule.foobar();
});

Some background: 一些背景:

Actually, CommonJS is much more than an API declaration and only a part of it deals with that. 实际上, CommonJS不仅仅是一个API声明,而且其中只有一部分处理该声明。 AMD started as a draft specification for the module format on the CommonJS list, but full consensus wasn't reached and further development of the format moved to the amdjs group . AMD最初是CommonJS列表中模块格式的规范草案,但尚未达成完全共识,因此该格式的进一步开发移交给了amdjs组 。 Arguments around which format is better state that CommonJS attempts to cover a broader set of concerns and that it's better suited for server side development given its synchronous nature, and that AMD is better suited for client side (browser) development given its asynchronous nature and the fact that it has its roots in Dojo's module declaration implementation. 关于哪种格式更好的争论指出,CommonJS试图涵盖更广泛的关注点,并且鉴于其同步特性,它更适合于服务器端开发,而鉴于其异步特性和特性,AMD更适合于客户端(浏览器)开发。它起源于Dojo的模块声明实现这一事实。

Sources: 资料来源:

  • RequireJS - Why AMD? RequireJS-为什么选择AMD?
  • Addy Osmani - Learning JavaScript Design Patterns - Modern Modular JavaScript Design Patterns Addy Osmani-学习JavaScript设计模式-现代模块化JavaScript设计模式

#5楼

Quoting 报价单

AMD : AMD

  • One browser-first approach 一种浏览器优先的方法
  • Opting for asynchronous behavior and simplified backwards compatibility 选择异步行为并简化向后兼容性
  • It doesn't have any concept of File I/O. 它没有文件I / O的任何概念。
  • It supports objects, functions, constructors, strings, JSON and many other types of modules. 它支持对象,函数,构造函数,字符串,JSON和许多其他类型的模块。

CommonJS : CommonJS

  • One server-first approach 一种服务器优先的方法
  • Assuming synchronous behavior 假设同步行为
  • Cover a broader set of concerns such as I/O, File system, Promises and more. 涵盖更广泛的关注点,例如I / O,文件系统,承诺等。
  • Supports unwrapped modules, it can feel a little more close to the ES.next/Harmony specifications, freeing you of the define() wrapper that AMD enforces. 支持展开的模块,它感觉更接近ES.next/Harmony规范,从而使您摆脱了AMD强制执行的define()包装器。
  • Only support objects as modules. 仅支持将对象作为模块。

#6楼

It is quite normal to organize JavaScript program modular into several files and to call child-modules from the main js module . 将JavaScript程序模块化组织成几个文件并从main js module调用child-modules是很正常的。

The thing is JavaScript doesn't provide this. 问题是JavaScript不提供此功能。 Not even today in latest browser versions of Chrome and FF. 直到今天,最新版的Chrome和FF浏览器都没有。

But, is there any keyword in JavaScript to call another JavaScript module? 但是,JavaScript中是否有关键字可以调用另一个JavaScript模块?

This question may be a total collapse of the world for many because the answer is No . 这个问题可能是世界完全崩溃了很多,因为答案是没有


In ES5 ( released in 2009 ) JavaScript had no keywords like import , include , or require . 在ES5(于2009年发布)中,JavaScript没有诸如importincluderequire之类的关键字。

ES6 saves the day ( released in 2015 ) proposing the import keyword ( https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/import ), but no browser implements this. ES6节省了建议使用import关键字( https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/import )的日期(2015年发布),但是没有浏览器实现此目的。

If you use Babel 6.18.0 and transpile with ES2015 option only 如果您使用Babel 6.18.0并仅通过ES2015选项进行转换

import myDefault from "my-module";

you will get require again. 您将再次获得require

"use strict";
var _myModule = require("my-module");
var _myModule2 = _interopRequireDefault(_myModule);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

This is because require means the module will be loaded from Node.js. 这是因为require意味着将从Node.js加载模块。 Node.js will handle everything from system level file read to wrapping functions into the module. Node.js将处理从系统级文件读取到将函数包装到模块中的所有内容。

Because in JavaScript functions are the only wrappers to represent the modules. 因为在JavaScript中,函数是表示模块的唯一包装。

I'm a lot confused about CommonJS and AMD? 我对CommonJS和AMD感到困惑?

Both CommonJS and AMD are just two different techniques how to overcome the JavaScript "defect" to load modules smart. CommonJS和AMD都是仅两种不同的技术,可以克服JavaScript的“缺陷”以智能地加载模块。

你可能感兴趣的:(javascript,module,requirejs,amd,commonjs)