? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?為什么需要模塊化
?JavaScript原始功能
在網(wǎng)頁(yè)開(kāi)發(fā)的早期,js制作作為一種腳本語(yǔ)言,做一些簡(jiǎn)單的表單驗(yàn)證或動(dòng)畫(huà)實(shí)現(xiàn)等,那個(gè)時(shí)候代碼還是很少的。
那個(gè)時(shí)候的代碼是怎么寫(xiě)的呢?直接將代碼寫(xiě)在<script>標(biāo)簽中即可
隨著ajax異步請(qǐng)求的出現(xiàn),慢慢形成了前后端的分離
客戶端需要完成的事情越來(lái)越多,代碼量也是與日俱增。
為了應(yīng)對(duì)代碼量的劇增,我們通常會(huì)將代碼組織在多個(gè)js文件中,進(jìn)行維護(hù)。
但是這種維護(hù)方式,依然不能避免一些災(zāi)難性的問(wèn)題。
比如全局變量同名問(wèn)題:看右邊的例子
另外,這種代碼的編寫(xiě)方式對(duì)js文件的依賴(lài)順序幾乎是強(qiáng)制性的
但是當(dāng)js文件過(guò)多,比如有幾十個(gè)的時(shí)候,弄清楚它們的順序是一件比較同時(shí)的事情。
而且即使你弄清楚順序了,也不能避免上面出現(xiàn)的這種尷尬問(wèn)題的發(fā)生。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 匿名函數(shù)的解決方案
我們可以使用匿名函數(shù)來(lái)解決方面的重名問(wèn)題
在aaa.js文件中,我們使用匿名函數(shù)

但是如果我們希望在main.js文件中,用到flag,應(yīng)該如何處理呢?
顯然,另外一個(gè)文件中不容易使用,因?yàn)閒lag是一個(gè)局部變量。
使用模塊作為出口
我們可以使用將需要暴露到外面的變量,使用一個(gè)模塊作為出口,什么意思呢?
來(lái)看下對(duì)應(yīng)的代碼:
我們做了什么事情呢?
非常簡(jiǎn)單,在匿名函數(shù)內(nèi)部,定義一個(gè)對(duì)象。
給對(duì)象添加各種需要暴露到外面的屬性和方法(不需要暴露的直接定義即可)。
最后將這個(gè)對(duì)象返回,并且在外面使用了一個(gè)MoudleA接受。
接下來(lái),我們?cè)趍ain.js中怎么使用呢?
我們只需要使用屬于自己模塊的屬性和方法即可
這就是模塊最基礎(chǔ)的封裝,事實(shí)上模塊的封裝還有很多高級(jí)的話題:
但是我們這里就是要認(rèn)識(shí)一下為什么需要模塊,以及模塊的原始雛形。
幸運(yùn)的是,前端模塊化開(kāi)發(fā)已經(jīng)有了很多既有的規(guī)范,以及對(duì)應(yīng)的實(shí)現(xiàn)方案。
常見(jiàn)的模塊化規(guī)范:
CommonJS、AMD、CMD,也有ES6的Modules

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? CommonJS(了解)
模塊化有兩個(gè)核心:導(dǎo)出和導(dǎo)入
CommonJS的導(dǎo)出:

CommonJS的導(dǎo)入

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ES6的export和import
export基本使用
export指令用于導(dǎo)出變量,比如下面的代碼:?

上面的代碼還有另外一種寫(xiě)法:

導(dǎo)出函數(shù)或類(lèi)
上面我們主要是輸出變量,也可以輸出函數(shù)或者輸出類(lèi)
上面的代碼也可以寫(xiě)成這種形式:

export default
某些情況下,一個(gè)模塊中包含某個(gè)的功能,我們并不希望給這個(gè)功能命名,而且讓導(dǎo)入者可以自己來(lái)命名
這個(gè)時(shí)候就可以使用export default

我們來(lái)到main.js中,這樣使用就可以了
這里的myFunc是我自己命名的,你可以根據(jù)需要命名它對(duì)應(yīng)的名字

另外,需要注意:
export default在同一個(gè)模塊中,不允許同時(shí)存在多個(gè)。