什么是模塊化
模塊化就是把一個(gè)文件看成一個(gè)模塊。每個(gè)模塊有自己的命名空間。
如何模塊化
使用立即執(zhí)行表達(dá)式來(lái)創(chuàng)建單獨(dú)的命令空間。例:
var module = (function() {
var num = 1;
return {
get: function () {
return num;
},
set: function (value) {
num = value;
}
}
})();
這段代碼定義了module模塊,有g(shù)et和set兩個(gè)方法??梢园裮odule看做一個(gè)單例。事實(shí)上模塊和單例還是挺像的。
模塊的依賴關(guān)系
如果模塊A需要引用模塊B,我們稱為模塊A依賴模塊B。
在加載模塊時(shí),就必須讓模塊B先加載,然后再加載模塊A才能不出錯(cuò)。
比如有兩個(gè)類,做成兩個(gè)模塊,分別是Animal和Cat,Cat繼承Animal,那么就需要把Animal放在Cat前面。
當(dāng)模塊數(shù)量變多時(shí),處理模塊的依賴就比較麻煩,需要一個(gè)模塊管理工具。
為什么需要require來(lái)引入模塊,有什么好處?
使用模塊管理器后,我們需要安裝規(guī)范來(lái)寫模塊。比如用module.exports來(lái)暴露接口,然后用require(或者import,視規(guī)范而定)來(lái)引入模塊。
通常情況下我們會(huì)在html中引入文件(模塊),例:
<script src="A.js"></script>
<script src="B.js"></script>
<script src="C.js"></script>
<script src="D.js"></script>
模塊的引入依靠html,而且需要排好順序。
用require可以通過(guò)js代碼來(lái)引入模塊,而不需要依靠html。
而且用require可以自動(dòng)根據(jù)調(diào)用順序來(lái)加載模塊。
想一想在NodeJS中,根本就沒(méi)有html,想要引入模塊只能用require。
模塊化規(guī)范
目前有3種規(guī)范
- commonJS
- AMD
- CMD
commonJS規(guī)范 NodeJS
commonJS規(guī)范的實(shí)現(xiàn)者是NodeJS。
commonJS是同步加載模塊的,適合從本地加載文件,適用于后端。
一個(gè)文件就是一個(gè)模塊,我們不需要自己使用立即執(zhí)行的匿名函數(shù)來(lái)創(chuàng)建命名空間。NodeJS會(huì)自動(dòng)對(duì)引入的文件套上一層立即執(zhí)行的匿名函數(shù)。
//模塊A
//導(dǎo)出接口 其實(shí)就是導(dǎo)出一個(gè)object,這個(gè)object有g(shù)et方法,
var num=1
function get(){
return num
}
module.exports={
get:get
}
//模塊B
//用require引入模塊A 然后調(diào)用A的方法
var moduleA=require("./a.js") //前面一定要加./ 不然會(huì)報(bào)錯(cuò)
var num=moduleA.get()
注意:模塊就和單例一樣,第一次require時(shí)運(yùn)行一次并返回exports的object,之后重復(fù)require都不會(huì)再運(yùn)行(不管在哪require都一樣),直接返回exports的object。(這是NodeJS模塊管理器的功能)
AMD規(guī)范 requireJS
AMD規(guī)范的實(shí)現(xiàn)者是requireJS
AMD是異步加載模塊的,適用于前端。
定義模塊:
define(模塊名,依賴的其他模塊,factory)
例:
//第一個(gè)參數(shù)模塊名其實(shí)沒(méi)啥用,可以不寫。有路徑就可以引入模塊了
//定義模塊A,沒(méi)有依賴其他模塊
//A.js文件
define(function(){
function getNum(){
return 1
}
return {
getNum:getNum
}
})
//定義模塊B,依賴模塊A,function里面的參數(shù)和依賴的模塊對(duì)應(yīng)
//["moduleA"]可以寫成["moduleA.js"] 或者["./moduleA.js"]
//B.js文件
define(["moduleA"],function(moduleA){
var index=moduleA.getNum();
return{
addIndex:function(){
index+=1
}
}
}
//加載模塊
require(["moduleA","moduleB"],function(moduleA,moduleB){
})
CMD規(guī)范
通用模塊定義,實(shí)現(xiàn)者有seaJS,目前很少用了
ES6的模塊加載
使用improt引入模塊
參考:http://es6.ruanyifeng.com/?search=module&x=5&y=8#docs/module
r.js
由于模塊化后,一個(gè)模塊一個(gè)文件,會(huì)導(dǎo)致文件數(shù)量過(guò)多,http請(qǐng)求數(shù)過(guò)多,網(wǎng)頁(yè)打開(kāi)變慢。
r.js是requrieJS的優(yōu)化工具,可以合并requireJS文件。
工程化
模塊之間的分析和查找其實(shí)可以在線下完成,所以有了工程化的概念。
公國(guó)webpack來(lái)智能分析模塊間的依賴,合理合并和壓縮模塊。使得開(kāi)發(fā)時(shí)可以以模塊化開(kāi)發(fā),發(fā)布時(shí)可以壓縮成單個(gè)文件。