- CommonJS規(guī)范加載模塊是同步的,只有加載完成,才能執(zhí)行后面的操作。
- AMD規(guī)范是非同步加載模塊,允許指定回調(diào)函數(shù)。
由于Node.js主要用于服務(wù)器編程,模塊文件一般都已經(jīng)存在于本地硬盤,所以加載起來比較快,不用考慮非同步加載的方式,所以CommonJS規(guī)范比較適用。但是,如果是瀏覽器環(huán)境,要從服務(wù)器端加載模塊,這時(shí)就必須采用非同步模式,因此瀏覽器端一般采用AMD規(guī)范。
CommonJS規(guī)范中的module、exports和require
- 每個(gè)文件就是一個(gè)模塊,有自己的作用域。每個(gè)模塊內(nèi)部,
module變量代表當(dāng)前模塊,是一個(gè)對(duì)象,它的exports屬性(即module.exports)是對(duì)外的接口。 -
module.exports屬性表示當(dāng)前模塊對(duì)外輸出的接口,其他文件加載該模塊,實(shí)際上就是讀取module.exports變量。 - 為了方便,
Node為每個(gè)模塊提供一個(gè)exports變量,指向module.exports。let exports = module.exports; -
require命令用于加載模塊文件。
使用示例:
//name.js
exports.name = function(){return '李婷婷'}; //導(dǎo)出
//getName.js
let getName = require('name'); //引入
注:不能直接將exports變量指向一個(gè)值,因?yàn)檫@樣等于切斷了exports與module.exports的聯(lián)系:如下
exports = function(x){console.log(x)}
如果一個(gè)模塊的對(duì)外接口,就是一個(gè)單一的值,不能使用exports輸出,只能使用module.exports輸出。
AMD/CMD規(guī)范
-
AMD是RequireJS在推廣過程中對(duì)模塊定義的規(guī)范化產(chǎn)出。
CMD是SeaJS在推廣過程中對(duì)模塊定義的規(guī)范化產(chǎn)出。 - 對(duì)于依賴的模塊,
AMD是提前執(zhí)行,CMD是延遲執(zhí)行。不過RequireJS從2.0開始,也改成可以延遲執(zhí)行(根據(jù)寫法不同,處理方式不同)。CMD推崇as lazy as possible. -
CMD推崇依賴就近,AMD推崇依賴前置。
//CMD
define(function(require, exports, module) {
let a = require('./a');
a.doSomething();
···
let b = require('./b'); // 依賴可以就近書寫
b.doSomething();
...
})
// AMD 默認(rèn)推薦的是
define(['./a', './b'], function(a, b) {
// 依賴必須一開始就寫好
a.doSomething()
...
b.doSomething()
...
})
雖然AMD也支持CMD的寫法,同時(shí)還支持將require作為依賴項(xiàng)傳遞,但RequireJS的作者默認(rèn)是最喜歡上面的寫法,也是官方文檔里默認(rèn)的模塊定義寫法。
-
AMD的API默認(rèn)是一個(gè)當(dāng)多個(gè)用,CMD的API嚴(yán)格區(qū)分,推崇職責(zé)單一。
比如AMD里,require分全局require和局部require,都叫 require。CMD里,沒有全局require,而是根據(jù)模塊系統(tǒng)的完備性,提供seajs.use來實(shí)現(xiàn)模塊系統(tǒng)的加載啟動(dòng)。CMD里,每個(gè)API都簡(jiǎn)單純粹。
拓展
目前所有的引擎都還沒有實(shí)現(xiàn)import,在node中使用babel支持ES6,也僅僅是將ES6轉(zhuǎn)碼為ES5再執(zhí)行,import語法會(huì)被轉(zhuǎn)碼為require。這也是為什么在模塊導(dǎo)出時(shí)使用module.exports,在引入模塊時(shí)使用import仍然起效,因?yàn)楸举|(zhì)上,import會(huì)被轉(zhuǎn)碼為require去執(zhí)行。
參考文檔
CommonJS規(guī)范
AMD 和 CMD 的區(qū)別有哪些?
Node中沒搞明白require和import,你會(huì)被坑的很慘