如今模塊化的 JavaScript 的開(kāi)發(fā)越來(lái)越火熱,無(wú)論是模塊加載器還是優(yōu)秀的 JavaScript 模塊,都是層出不窮。既然這么火,肯定是有存在的理由,肯定是解決了某些實(shí)際問(wèn)題。很多沒(méi)接觸過(guò)模塊化 JavaScript 開(kāi)發(fā)者不禁要問(wèn),我真的需要模塊化嗎,模塊化相比于傳統(tǒng)的模式有什么優(yōu)勢(shì)?
JavaScript 本身是沒(méi)有模塊化支持的,很多語(yǔ)言都有,就連CSS都有這樣的加載方式。
@import "fed.css";
雖然因?yàn)樾阅軉?wèn)題不推薦CSS這樣來(lái)進(jìn)行加載,但這是一種模塊化的思想,這種思想對(duì)于 JavaScript 來(lái)說(shuō)很有用。幸好JavaScript是一門(mén)靈活的語(yǔ)言,可以通過(guò)下面這段代碼來(lái)進(jìn)行動(dòng)態(tài)加載 JavaScript 文件。
var script = document.createElement( 'script' ),
head = document.head;
script.src = 'http://example.com/test.js';
script.async = 'async';
head.insertBefore( script, head.firstChild );
傳統(tǒng)的加載方式必須在頁(yè)面中放置一個(gè) script 標(biāo)簽來(lái)進(jìn)行加載。
<script type="text/javascript" src="http://example.com/test.js"></script>
更好的分離
那如果要加載多個(gè)就得放置多個(gè) script 標(biāo)簽,如果是加載模塊的話,拿 easy.js 來(lái)說(shuō),頁(yè)面中始終只要引用 easy.js 即可,這樣對(duì)于 HTML 和 JavaScript 分離很有好處,在某些場(chǎng)景下這個(gè)分離度很重要。
就拿我司的情況來(lái)說(shuō)吧。后端的 view 層并不是由我們前端來(lái)開(kāi)發(fā)的,項(xiàng)目上線的時(shí)候,前端只能更新 CSS 和 JS 文件,HTML 文件動(dòng)不了。如果前端要在該頁(yè)面新增一個(gè) JavaScript 文件的引用是很麻煩的,因?yàn)楹蠖顺绦虻母露家獓?yán)格按照流程來(lái)并有固定的更新時(shí)間,如果是用模塊加載的方式不用再理會(huì)后端的更新。當(dāng)然,你也許會(huì)說(shuō),如果原頁(yè)面中已經(jīng)有 JavaScript 文件,我直接在原文件中加代碼不就行了,那么接下來(lái)說(shuō)說(shuō)直接在原文件中新增代碼會(huì)碰到什么樣的問(wèn)題。
更好的代碼組織方式
如果單個(gè)文件越來(lái)越大,維護(hù)起來(lái)出問(wèn)題的幾率也會(huì)越來(lái)越大,一個(gè)人開(kāi)發(fā)還好,如果是多人開(kāi)發(fā),不同的代碼風(fēng)格,超多的業(yè)務(wù)邏輯混雜在一起,不要說(shuō)維護(hù)了,光想想都蛋痛。模塊式的開(kāi)發(fā),一個(gè)文件就是一個(gè)模塊,控制了文件的粒度,每個(gè)模塊可以專注于一個(gè)功能。正所謂一個(gè)蘿卜一個(gè)坑,多人開(kāi)發(fā)時(shí),各自管好自己坑里的蘿卜就行了,這也正是 OOP 的思想。
按需加載
還是圍繞單個(gè)文件來(lái)說(shuō)事,當(dāng)文件大到一定的程度,性能問(wèn)題也隨之而來(lái)了。合并文件是能減少請(qǐng)求,這是會(huì)帶來(lái)性能的提升,但是當(dāng)文件大到一定的體積時(shí),此時(shí)的下載時(shí)間可能并不會(huì)比多個(gè)小文件的下載時(shí)間更短。此時(shí)就需要權(quán)衡請(qǐng)求數(shù)和文件體積的關(guān)系了。
單文件還有一個(gè)問(wèn)題,那就是緩存是否能充分的利用好。如果一個(gè)大體積的文件內(nèi)包含了超多的業(yè)務(wù)邏輯和復(fù)雜的功能,而這個(gè)文件同時(shí)又被很多頁(yè)面引用到。比如在某頁(yè)面,實(shí)際只用到了該文件一個(gè)很少的功能,那么其他的代碼對(duì)于該頁(yè)面來(lái)說(shuō)就是多余的,浪費(fèi)了加載流量。你或許會(huì)說(shuō),這個(gè)文件雖然大,但是它第一次加載的時(shí)候就被緩存過(guò)了,盡管在某頁(yè)面只用到了極少部分的功能,但只要緩存過(guò),加載還是挺快的。是的,如果情況有這么理想肯定是好事。但是,往往理想和現(xiàn)實(shí)都會(huì)有差距,如果產(chǎn)品的迭代更新太快,業(yè)務(wù)需求一天一個(gè)樣,那么該文件就會(huì)三天兩頭的更新,更新可能是一個(gè)很小的功能,但是這樣的更新對(duì)于刷新緩存的代價(jià)可是很大的。如果確實(shí)有這種情況,就說(shuō)明這種設(shè)計(jì)確實(shí)是有問(wèn)題。如果能合理的對(duì)文件進(jìn)行模塊化的管理,那么可以盡量減少不必要的加載,盡量減少刷新大文件的緩存帶來(lái)的損失,這也需要權(quán)衡好,比如將很少更新的合并成一個(gè)文件,常更新的獨(dú)立成模塊。
避免命名沖突
JavaScript 本身是沒(méi)有命名空間的,為了避免命名沖突,經(jīng)常會(huì)使用對(duì)象和閉包的辦法來(lái)避免。用對(duì)象僅僅是降低了沖突的概率而已,拿經(jīng)常使用 jQuery 的開(kāi)發(fā)來(lái)說(shuō),無(wú)論是往 $ 上擴(kuò)展還是在 $.fn 上擴(kuò)展,人多了難免會(huì)起沖突。或者用自定義的對(duì)象,搞個(gè)好幾層,不光是寫(xiě)起來(lái)難記,這樣的調(diào)用也會(huì)在性能上打折扣的。模塊化就很好的解決了這個(gè)問(wèn)題,在該模塊內(nèi)的任何形式的命名都不會(huì)再和其他模塊有沖突,你想起啥名都行了。當(dāng)然,你硬要在模塊內(nèi)部給 window 上掛一堆東西,我也沒(méi)辦法。
既然每個(gè)模塊都是封閉式的,那么模塊之間如何通信呢?接口的設(shè)計(jì)那是必須的。很簡(jiǎn)單,對(duì)于像 seajs 這種 CMD 規(guī)范的,需要使用自定義的關(guān)鍵字來(lái)向外部暴露一個(gè)接口。
define(function( require, exports ){
var hello = 'hello world';
// 向外部暴露該模塊的接口
exports.hello = hello;
});
easy.js 遵循 AMD 規(guī)范,暴露接口更簡(jiǎn)單,直接用 return 關(guān)鍵詞即可。
define( 'hello', function(){
var hello = 'hello world';
// 向外部暴露該模塊的接口
return hello;
});
更好的依賴處理
傳統(tǒng)的開(kāi)發(fā)模式,如果 B 文件要依賴 A 文件,那么必須在 B 文件前面用 script 的形式先加載好 A 文件。如果有一天,B 文件不再需要依賴 A 文件,或者要增加依賴文件 C,那么又回到了我說(shuō)的第一個(gè)問(wèn)題上。如果這個(gè) B 文件被 N 個(gè)頁(yè)面在調(diào)用,而且頁(yè)面還跨業(yè)務(wù)站點(diǎn),那改起來(lái)簡(jiǎn)直就是噩夢(mèng)啊。如果是用模塊化,只需要在模塊內(nèi)部聲明好依賴就行了,增加刪除都直接修改模塊即可。調(diào)用的時(shí)候也不用管該模塊依賴了哪些其他模塊,放心的用就是了。
本文來(lái)自成都品牌網(wǎng)站建設(shè)網(wǎng)站設(shè)計(jì)公司-創(chuàng)新互聯(lián)
本文標(biāo)題:模塊化相比于傳統(tǒng)的模式有什么優(yōu)勢(shì)?
網(wǎng)頁(yè)鏈接:http://www.rwnh.cn/news47/326547.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動(dòng)態(tài)網(wǎng)站、虛擬主機(jī)、ChatGPT、企業(yè)網(wǎng)站制作、軟件開(kāi)發(fā)、網(wǎng)站營(yíng)銷
廣告
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源:
創(chuàng)新互聯(lián)