以前,我們的javascript是沒有模塊化的,通常一個頁面引對應(yīng)的js, 如index.html引入index.js來實現(xiàn)1主頁的輪播圖,點擊跳轉(zhuǎn)等功能,就那樣一個功能一個功能寫了下來,無法將一個大程序拆分成一個一個小模塊,后來js壯大了,也復(fù)雜了,社區(qū)首先推出了用于服務(wù)器端的common.js和用戶瀏覽器環(huán)境的amd,再后來es6在語言層面,自己實現(xiàn)了模塊化加載方案,我們主要看看他們的區(qū)別
ES6 模塊的設(shè)計思想是盡量的靜態(tài)化,使得編譯時就能確定模塊的依賴關(guān)系,以及輸入和輸出的變量。CommonJS 和 AMD 模塊,都只能在運行時確定這些東西。比如,CommonJS 模塊就是對象,輸入時必須查找對象屬性。
let {a , b ,c } = require('fs') 相當(dāng)于 let _fs = require('fs') let a = _fs.a
1 common.js與amd實際上是先整體加載fs模塊,即加載fs模塊下的所有方法,生成一個對象_fs,再從這個對象身上加載其他然后再從這個對象上面讀取 3 個方法。這種加載稱為“運行時加載”,因為只有運行時才能得到這個對象,導(dǎo)致完全沒辦法在編譯時做“靜態(tài)優(yōu)化”。
ES6 模塊不是對象,而是通過export命令顯式指定輸出的代碼,再通過import命令輸入。
// ES6模塊
import { stat, exists, readFile } from 'fs';
上面代碼的實質(zhì)是從fs模塊加載 3 個方法,其他方法不加載。這種加載稱為“編譯時加載”或者靜態(tài)加載,即 ES6 可以在編譯時就完成模塊加載,效率要比 CommonJS 模塊的加載方式高。當(dāng)然,這也導(dǎo)致了沒法引用 ES6 模塊本身,因為它不是對象。
由于 ES6 模塊是編譯時加載,使得靜態(tài)分析成為可能。有了它,就能進(jìn)一步拓寬 JavaScript 的語法,比如引入宏(macro)和類型檢驗(type system)這些只能靠靜態(tài)分析實現(xiàn)的功能。
除了靜態(tài)加載帶來的各種好處,ES6 模塊還有以下好處。
不再需要UMD模塊格式了,將來服務(wù)器和瀏覽器都會支持 ES6 模塊格式。目前,通過各種工具庫,其實已經(jīng)做到了這一點。
將來瀏覽器的新 API 就能用模塊格式提供,不再必須做成全局變量或者navigator對象的屬性。 不再需要對象作為命名空間(比如Math對象),未來這些功能可以通過模塊提供。