JavaScript在es6之前,本身并不支持模塊化,隨著前端項(xiàng)目的日益復(fù)雜化,大型化,讓JavaScript不得不做模塊化.現(xiàn)在主要有如下模塊化解決方案:
這里不討論各個(gè)模塊化解決方案的使用,而是討論區(qū)別是應(yīng)用場(chǎng)景等
- AMD(require.js)
- CMD(sea.js)
- Common.js(node.js支持)
- UMD
- ESM(es6官方支持)
1. AMD和CMD
AMD和CMD是JavaScript中出現(xiàn)較早的模塊化解決方案,且都服務(wù)于瀏覽器端,因此放在一起看.
AMD(Asynchronous Module Definition),采用異步加載模塊,主要服務(wù)于瀏覽器端.
CMD(Common Module Definition),主要服務(wù)于瀏覽器端.
區(qū)別
- 加載和執(zhí)行順序不同
AMD官方推薦依賴前置加載并執(zhí)行,而后執(zhí)行模塊內(nèi)容; 2.0后也支持就近加載,但是依然不是官方推薦.
CMD推薦就近加載. - 對(duì)第三方庫(kù)友好度
CMD的實(shí)現(xiàn)sea.js取義海納百川,不強(qiáng)行要求別的庫(kù)遵循CMD標(biāo)準(zhǔn),但是能很好的兼容之.本人經(jīng)過(guò)項(xiàng)目實(shí)踐,覺(jué)得優(yōu)于require.js.
AMD不那么友好
2.CommonJS
CommonJS主要服務(wù)于服務(wù)端,目前node.js支持CommonJS.
CommonJS同步加載模塊,一個(gè)單獨(dú)的文件就是一個(gè)模塊,輸出的是一個(gè)值的拷貝.
3.UMD
UMD是是AMD和CommonJS的結(jié)合.先判斷是否是Node.js環(huán)境(node支持的exports是否存在), 在判斷是否是AMD環(huán)境
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.libName = factory());
}(this, (function () { 'use strict';})));
4.ESM
es6推出的JavaScript模塊化標(biāo)準(zhǔn).
使用類似類型化語(yǔ)言的import和export
是靜態(tài)化的模塊系統(tǒng),輸出值只是一個(gè)引用,利于做代碼靜態(tài)分析.
5.ESM和CommonJS區(qū)別
- 最大的區(qū)別是ESM輸出值的引用,CommonJS輸出值的拷貝; 意味著ESM模塊內(nèi)部變化,會(huì)影響外部使用. 但是CommonJS模塊內(nèi)部變化不會(huì)影響外部.這也造成了兩者巨大的沖突,在node.js中很難兼容,在node.js中只能用mjs后綴來(lái)區(qū)分使用兩者.
- ESM靜態(tài)編譯,CommonJS運(yùn)行時(shí)加載.
- ESM的import和export會(huì)變量提升,優(yōu)先到頭部執(zhí)行; 但是CommonJS不會(huì)變量提升.