概述
模塊化是將系統(tǒng)分離成獨立功能的方法,這樣我們可以按需加載功能坊萝。
往往當(dāng)一個項目開發(fā)得越來越復(fù)雜時,可能會遇到這些些問題许起,例如:命名沖突十偶、文件依賴等。
總結(jié):在生產(chǎn)的角度园细,模塊化開發(fā)是一種生產(chǎn)方式惦积,這種方式生產(chǎn)效率高,維護(hù)成本低猛频。
模塊化開發(fā)演變
全局函數(shù)
在早期的開發(fā)過程中會將重復(fù)的代碼封裝搭到函數(shù)中狮崩,再將一系列的函數(shù)放到一個文件中。這種方式存在一些問題:存在污染全局變量鹿寻、看不出相互的直接關(guān)系睦柴。這種方式并不能解決根本的問題:命名沖突和文件依賴。
對象命名空間
通過對象命名空間的形式烈和,從某種程度上解決了變量命名沖突的問題爱只,但是并不能從根本上解決命名沖突。存在問題:內(nèi)部狀態(tài)可被外部改寫招刹、命名空間越來越長恬试。
私有公有成員分離
利用此種方式將函數(shù)包裝成一個獨立的作用域,私有空間的變量和函數(shù)不會影響到全局作用域疯暑。這種方式相當(dāng)于現(xiàn)在寫插件的形式训柴,解決了變量命名沖突的問題,但是沒有解決降低開發(fā)復(fù)雜度的問題妇拯。
CommonJS
CommonJS規(guī)范加載模塊是同步的幻馁,也就是說,加載完成才執(zhí)行后面的操作越锈。
CommonJS規(guī)范分為三部分:module(模塊標(biāo)識)仗嗦、require(模塊引用)、exports(模塊定義)甘凭。 module變量在每個模塊內(nèi)部稀拐,就代表當(dāng)前模塊; exports屬性是對外的接口丹弱,用于導(dǎo)出當(dāng)前模塊的方法或變量德撬;require()用來加載外部模塊铲咨,讀取并執(zhí)行js文件,返回該模塊的exports對象蜓洪。
AMD(reuire.js)
AMD也就是異步模塊定義纤勒,它采用異步方式加載模塊,主要針對的是瀏覽器端的模塊規(guī)范隆檀。它通過define方法去定義模塊摇天,require方法去加載模塊。
AMD定義:如果這個模塊還需要依賴其他模塊刚操,那么define函數(shù)的第一個參數(shù)闸翅,必須是一個數(shù)組,指明該模塊的依賴菊霜。
require(['modules'], callback);
第一個參數(shù)['modules']坚冀,是一個數(shù)組,里面的成員就是需要加載的模塊鉴逞;第二個參數(shù)callback记某,則是加載成功之后的回調(diào)函數(shù)。
CMD(sea.js)
CMD即通用模塊定義构捡,CMD規(guī)范是國內(nèi)發(fā)展出來的液南;正如AMD有require.js,CMD有個瀏覽器的實現(xiàn)sea.js勾徽。sea.js要解決的問題和require.js一樣滑凉,只不過在模塊定義方式和模塊加載方式上有所不同。
define(function (require, exports, module) {
// 模塊代碼
})
require是可以把其他模塊導(dǎo)入進(jìn)來的一個參數(shù)喘帚;exports可以把模塊內(nèi)的一些屬性和方法導(dǎo)出畅姊;module是一個對象,上面存儲了與當(dāng)前模塊相關(guān)聯(lián)的一些屬性和方法吹由。CMD是按需加載若未,推崇依賴就近,延遲執(zhí)行倾鲫。文件是提前加載好的粗合,只有在require的時候才去執(zhí)行文件;
ES6 Module
ES6模塊化汲取CommonJS和AMD的優(yōu)點乌昔,語法簡潔隙疚,支持異步加載,未來可以成為瀏覽器和服務(wù)器通用的模塊化解決方案磕道。
ES6中模塊的定義:ES6新增了兩個關(guān)鍵字:export和import甚淡。export用于把模塊里的內(nèi)容暴露出來,import用于引入模塊提供的功能。
ES6中模塊的加載贯卦,import加載模塊:
import{bar,foo,test,obj} from './lib'foo();
注意:可以使用export default命令,為模塊指定默認(rèn)輸出焙贷,一個模塊只能有一個默認(rèn)輸出撵割,所以export default只能使用一次。
ES6模塊運行機(jī)制:ES6模塊是動態(tài)引用辙芍,如果使用import從一個模塊加載變量(即import foo from 'foo')啡彬,變量不會被緩存,而是成為一個指向被加載模塊的引用故硅。等腳本執(zhí)行時庶灿,根據(jù)只讀引用,到被加載的那個模塊中去取值吃衅。