模塊的來(lái)源
最早的模塊機(jī)制出現(xiàn)在node,即common js, 因?yàn)楹蠖碎_(kāi)發(fā)比較的復(fù)雜,為了避免命名重復(fù)產(chǎn)生沖突同時(shí)也為了實(shí)現(xiàn)功能的復(fù)用,于是引入了模塊機(jī)制。
隨著前端開(kāi)發(fā)越來(lái)越復(fù)雜,一些底層的通用的功能可以抽象成函數(shù),同樣為了避免命名沖突,前端JS也引入了模塊機(jī)制。
前后端模塊規(guī)范
現(xiàn)在我們接觸到四種模塊規(guī)范:
- node的common js
- AMD
- CMD
- es6中的模塊
common js
基本概念
node應(yīng)用由模塊組成,采用commonJS模塊規(guī)范,具體而言,每個(gè)文件都是一個(gè)模塊,模塊內(nèi)的變量函數(shù)對(duì)象都是文件私有的,CommonJS定義的模塊分為:
模塊引用(require):用來(lái)引入外部模塊,
模塊定義(exports):用于導(dǎo)出當(dāng)前模塊的方法或變量,唯一的導(dǎo)出口,
模塊標(biāo)識(shí)(module):代表模塊本身,
優(yōu)點(diǎn):
1.解決了變量污染問(wèn)題,每個(gè)模塊具有獨(dú)立的空間,互不干擾。
2.支持引入導(dǎo)出功能,可以連接各個(gè)模塊,實(shí)現(xiàn)彼此間的依賴。
3.接口簡(jiǎn)潔,定義模塊十分簡(jiǎn)單。
缺點(diǎn):
1.只適用于后端,不適合瀏覽器端。
具體寫法
//math.js
module.exports = function (){}
//foo.js
var math = require('./math')
AMD && CMD
為什么前端不用common js?
因?yàn)閏ommonjs是同步的,也就是require的過(guò)程中,必須完成這個(gè)加載動(dòng)作后面的代碼才會(huì)執(zhí)行,這對(duì)服務(wù)器端不是一個(gè)問(wèn)題,因?yàn)樗械哪K都存放在本地硬盤,可以同步加載完成,等待時(shí)間就是硬盤的讀取時(shí)間。這種形式不適合于瀏覽器場(chǎng)景,因?yàn)槟K都放在服務(wù)器端,等待時(shí)間取決于網(wǎng)速的快慢,可能要等很長(zhǎng)時(shí)間,瀏覽器處于"假死"狀態(tài),所以瀏覽器加載需要異步加載。
AMD
基本概念
AMD意思是異步模塊定義,它采用異步方式加載模塊,模塊的加載不影響它后面語(yǔ)句的運(yùn)行。所有依賴這個(gè)模塊的語(yǔ)句,都定義在一個(gè)回調(diào)函數(shù)中,等到加載完成之后,這個(gè)回調(diào)函數(shù)才會(huì)運(yùn)行。AMD 是基于require.js實(shí)現(xiàn)的。
具體寫法
定義:define()
// math.js
define([module1, module2], function (module1, module2) {})
引入使用:require()
// main.js
require(['math'], function (math){})
CMD
基本概念
CMD是基于sea.js實(shí)現(xiàn)的, 一個(gè)模塊就是一個(gè)文件,它既遵循了amd規(guī)范,又遵循commonJs規(guī)范。
define:一個(gè)全局函數(shù),用來(lái)定義模塊,接受對(duì)象,字符串,函數(shù)作為參數(shù),當(dāng)參數(shù)為函數(shù)時(shí),函數(shù)的參數(shù)有(require,exports,module)。
require:是一個(gè)方法,接受 模塊作為唯一參數(shù),用來(lái)獲取其他模塊提供的接口。
exports:是一個(gè)對(duì)象,用來(lái)向外提供模塊接口。
具體用法
define(function(require,exports,module){
var a = require('./a')
// do something
var b = require('/b')
// do something
module.exports = ...
})
更多詳情見(jiàn)鏈接:https://github.com/seajs/seajs/issues/242
AMD和 CMD的區(qū)別
- 對(duì)于依賴的模塊,AMD 是提前執(zhí)行,CMD 是延遲執(zhí)行。不過(guò) RequireJS 從 2.0 開(kāi)始,也改成可以延遲執(zhí)行(根據(jù)寫法不同,處理方式不同)。CMD 推崇 as lazy as possible.
- CMD 推崇依賴就近,AMD 推崇依賴前置。
es6 模塊
基本概念
在es6中實(shí)現(xiàn)了模塊功能,而且可以通用于服務(wù)器和瀏覽器,es6模塊的設(shè)計(jì)思想是盡量的靜態(tài)化,使得編譯時(shí)就確定模塊的依賴關(guān)系,以及輸入和輸出的變量(之前的common js AMD都只能在運(yùn)行時(shí)確定)。模塊功能主要由兩個(gè)命令構(gòu)成:
1.export:用于規(guī)定模塊的對(duì)外接口
2.import:用于輸入其他模塊提供的功能
具體用法
// a.js
export:
export var a = 'hello'
export function multiple (){}
等價(jià)于:
var a = 'hello'
function multiple (){}
export {a, multiple}
// b.js
import:
import {a, multiple} from 'a.js'
參考文檔:
https://www.cnblogs.com/chenguangliang/p/5856701.html (commom js AMD)
http://es6.ruanyifeng.com/#docs/module (es6)