以前,我們的javascript是沒有模塊化的晒骇,通常一個頁面引對應的js, 如index.html引入index.js來實現(xiàn)1主頁的輪播圖掐暮,點擊跳轉(zhuǎn)等功能涂佃,就那樣一個功能一個功能寫了下來,無法將一個大程序拆分成一個一個小模塊灵莲,后來js壯大了雕凹,也復雜了,社區(qū)首先推出了用于服務器端的common.js和用戶瀏覽器環(huán)境的amd政冻,再后來es6在語言層面枚抵,自己實現(xiàn)了模塊化加載方案,我們主要看看他們的區(qū)別
ES6 模塊的設(shè)計思想是盡量的靜態(tài)化赠幕,使得編譯時就能確定模塊的依賴關(guān)系俄精,以及輸入和輸出的變量。CommonJS 和 AMD 模塊榕堰,都只能在運行時確定這些東西竖慧。比如,CommonJS 模塊就是對象逆屡,輸入時必須查找對象屬性圾旨。
let {a , b ,c } = require('fs') 相當于 let _fs = require('fs') let a = _fs.a
1 common.js與amd實際上是先整體加載fs模塊,即加載fs模塊下的所有方法魏蔗,生成一個對象_fs砍的,再從這個對象身上加載其他然后再從這個對象上面讀取 3 個方法。這種加載稱為“運行時加載”莺治,因為只有運行時才能得到這個對象廓鞠,導致完全沒辦法在編譯時做“靜態(tài)優(yōu)化”帚稠。
ES6 模塊不是對象,而是通過export命令顯式指定輸出的代碼床佳,再通過import命令輸入滋早。
// ES6模塊
import { stat, exists, readFile } from 'fs';
上面代碼的實質(zhì)是從fs模塊加載 3 個方法,其他方法不加載砌们。這種加載稱為“編譯時加載”或者靜態(tài)加載杆麸,即 ES6 可以在編譯時就完成模塊加載,效率要比 CommonJS 模塊的加載方式高浪感。當然昔头,這也導致了沒法引用 ES6 模塊本身,因為它不是對象影兽。
由于 ES6 模塊是編譯時加載揭斧,使得靜態(tài)分析成為可能。有了它赢笨,就能進一步拓寬 JavaScript 的語法未蝌,比如引入宏(macro)和類型檢驗(type system)這些只能靠靜態(tài)分析實現(xiàn)的功能。
除了靜態(tài)加載帶來的各種好處茧妒,ES6 模塊還有以下好處。
不再需要UMD模塊格式了左冬,將來服務器和瀏覽器都會支持 ES6 模塊格式桐筏。目前,通過各種工具庫拇砰,其實已經(jīng)做到了這一點梅忌。
將來瀏覽器的新 API 就能用模塊格式提供,不再必須做成全局變量或者navigator對象的屬性除破。 不再需要對象作為命名空間(比如Math對象)牧氮,未來這些功能可以通過模塊提供。