隨著互聯(lián)網(wǎng)的快速發(fā)展,人們不單單只是需要一個(gè)網(wǎng)頁了,功能更復(fù)雜、交互更豐富的 WebAPP 成為開發(fā)者需要面對(duì)的日常工作內(nèi)容。隨之而來的是更加龐大與更加復(fù)雜的 JavaScript 代碼,如此而來,僅僅依靠著我們之前面向?qū)ο蟮?JavaScript 進(jìn)行代碼封裝已很難滿足生產(chǎn)需求,特別是在團(tuán)隊(duì)協(xié)作的復(fù)雜項(xiàng)目中,JavaScript 模塊化已成為一個(gè)迫切的需求。
原始社會(huì)的生產(chǎn)
開始的開始 Music ..?.?.?.?...我們都是...咳咳,我們都會(huì)使用如下的方式寫代碼,將獨(dú)立通用的的功能獨(dú)立成一個(gè)個(gè)函數(shù):
function bar(){
//do something
}
function log(){
//do something
}
這都是最初得美好,那些習(xí)以為常的習(xí)慣,回憶ing...這是最原始的模塊,需要使用調(diào)用就好。但是但是,使用過就會(huì)知道這樣會(huì)污染全局變量,并且很容易造成 命名沖突,好吧,它屬于最初的美好。
后來,為了解決上面青春期的問題,我們選擇了面向?qū)ο髮懛ǎ?Namespace (命名空間),將代碼進(jìn)行簡(jiǎn)單封裝:
var myModule = {
bar: function(){
//do something
},
log: function(){
//do something
}
}
//調(diào)用
myMoudle.bar();
這種方式看似還可以,減少了全局變量,能緩解嚴(yán)峻的問題。但是這并不安全,因?yàn)閷?shí)質(zhì)上是對(duì)象,會(huì)暴露所有的模塊成員,內(nèi)部狀態(tài)可以被外部讀寫。
沒辦法,出了問題繼續(xù)解決,我們采用匿名閉包的寫法(Immediately-Invoked Function Expression,IIFE):
var myModule = (function(){
var _log = "hello world";
var log = function(){
console.log(_log);
};
return {
log: log
}
})();
//引用
myModule.log();//hello world
myModule._log;//undefined
如此,外部就無法讀寫到內(nèi)部的成員(_log
)。這時(shí)候需求又改變了,你的模塊不再是簡(jiǎn)單的一個(gè)模塊,而是一個(gè)功能很大的模塊,需要分成幾個(gè)部分,這些部分存在相互之間的 依賴關(guān)系。好吧,我們來引入依賴:
var myModule = (function($){
var $log = $('.log');
var log = function(){
console.log($log);
};
return {
log: log
}
})(jQuery);
//引用
myModule.log();
這樣我們?cè)诖a中引入了jQuery,方法間存在依賴關(guān)系;
至此,我們用簡(jiǎn)陋的工具,和無比勤勞的雙手為子孫們搭建了發(fā)展的架子,為后續(xù)社會(huì)發(fā)展出更先進(jìn)好用的模塊化工具打下了基石,感謝祖輩們的探索!
文明社會(huì)的探索
飛速變化的年代里,人們總是不滿足于現(xiàn)狀。有了前人的封裝性還不夠,我們引入 JS 文件時(shí)是靠不斷追加 <script src=""></script>
標(biāo)簽得以實(shí)現(xiàn),每個(gè)標(biāo)簽引入順序是有要求的。
當(dāng)我們引入的文件增多,除了看起來比較累贅,還會(huì)出現(xiàn)比較多的依賴關(guān)系,而這種寫法是無法突出這種關(guān)系的,我們需要 依賴管理,也讓 后續(xù)維護(hù) 基本上變得無法進(jìn)行。
<script src="jquery.js"><script>
<script src="dialog.js"><script>
<script src="tooltip.js"><script>
<script src="toast.js"><script>
<script src="handlebar.js"><script>
......
很多時(shí)候可能就是由于之前沒有引入一個(gè)依賴的 js 文件而導(dǎo)致后面 js 的功能失效,瀏覽器報(bào)錯(cuò)。大型項(xiàng)目中,一些通用組件往往因此不能輕易地引入到業(yè)務(wù)代碼中去,生產(chǎn)效率低下。還有一個(gè)問題就是 請(qǐng)求過多,不利于性能優(yōu)化。
時(shí)代的進(jìn)步是注定需要出現(xiàn)偉人的,積累下的訴求注定是需要人來響應(yīng)的,一些規(guī)范橫空出世,諸如 CommonJS規(guī)范、AMD規(guī)范、CMD規(guī)范 等一幫豪杰之輩,懷揣濟(jì)世為民之心,度前端開發(fā)者于混沌之境。欲知其如何演繹,請(qǐng)看下篇 《前端模塊化之旅(二):CommonJS、AMD和CMD》。