最近在看 Vue.js 源碼的時候注意到構(gòu)建配置了多個不同的模塊輸出形式螺戳,分別是:CommonJS
鲜戒、UMD
以及 ES Module
令花,那么他們有什么區(qū)別呢漱挚,各自用在哪種場景里。
CommonJS
Node 應(yīng)用采用的模塊規(guī)范
每個文件就是一個模塊弦牡,有自己的作用域友驮。在一個文件里面定義的變量、函數(shù)驾锰、類卸留,都是私有的,對其他文件不可見椭豫。
CommonJS 特點:
所有代碼都運行在模塊作用域耻瑟,不會污染全局作用域。
模塊可以多次加載捻悯,但是只會在第一次加載時運行一次匆赃,然后運行結(jié)果就被緩存了淤毛,以后再加載今缚,就直接讀取緩存結(jié)果。要想讓模塊再次運行低淡,必須清除緩存姓言。
模塊加載的順序,按照其在代碼中出現(xiàn)的順序蔗蹋。
值得一提的是何荚,CommonJS 規(guī)范加載模塊是同步的,也就是說猪杭,只有加載完成餐塘,才能執(zhí)行后面的操作。AMD(Asynchronous Module Definition) 規(guī)范則是非同步加載模塊皂吮,允許指定回調(diào)函數(shù)戒傻。由于 Node.js 主要用于服務(wù)器編程,模塊文件一般都已經(jīng)存在于本地硬盤蜂筹,所以加載起來比較快需纳,不用考慮非同步加載的方式,所以 CommonJS 規(guī)范比較適合艺挪。但是不翩,如果是瀏覽器環(huán)境,要從服務(wù)器端加載模塊,這時就必須采用非同步模式口蝠,因此瀏覽器端一般采用 AMD 規(guī)范
browserify
和 webpack 1
可以直接加載 cjs 模塊形式
UMD
UMD(Universal Module Definition)提供了支持多種風(fēng)格的“通用”模式器钟,在兼容CommonJS和AMD規(guī)范的同時,還兼容全局引用的方式
UMD實現(xiàn)原理很簡單:
- 先判斷是否支持AMD(define 是否存在)妙蔗,存在則使用 AMD 方式加載模塊俱箱;
- 再判斷是否支持 Node.js 模塊格式(exports是否存在),存在則使用 Node.js 模塊格式灭必;
- 前兩個都不存在狞谱,則將模塊公開到全局(window 或 global)
UMD 使得你可以直接使用 <script>
標(biāo)簽引用
ES Module
ECMAScript 6 的一個目標(biāo)是解決作用域的問題,也為了使JS應(yīng)用程序顯得有序禁漓,于是引進了模塊跟衅。目前部分主流瀏覽器已原生支持ES Module,使用 type = module
指定為模塊引入即可
注意:使用該方式執(zhí)行 JS 時自動應(yīng)用 defer
屬性
Rollup
和 webpack 2+
可以直接加載 ES Module 形式