淺談模塊化


理論不能指導實踐,就是空談;技術不能解決問題,就是雞肋。

先來看看我們有什么問題

我們經常遇到的問題

每次開會,言必及CSS代碼難以管理和維護,冗余代碼多,耦合度高,修改的時候,只能不斷提升css選擇器的權重來覆蓋,相當痛苦。

js:不能按照功能和業務來組織代碼,到處都是 腳本引用, script標簽插入,全局變量污染,維護難,還很容易產生bug。

以上問題不解決,它會像一顆毒瘤一樣不斷生長,擴散,重構勢在必行。

但是在重構之前,有必要梳理一下導致今天這種局面的原因,對每一個原因進行深入分析,找到根源,采取對應的措施,才不會頭痛醫頭。

表面上,原因有以下幾點:

1、歷史遺留問題

這個問題客觀存在,但是...不重要的不細說。重要的是有沒有意識到前人為什么把這么嚴重的問題留給了我們,答案其實也相當明了,因為css開發就是這樣的,沒有變量緩存,沒有流程控制,能做的太少了,只能從頭寫到尾。css的這種問題幾乎是普遍性的,很多大廠的大牛們也常常發文,怨聲載道。

2、我們因為不敢動前人的代碼,只能沿着這條道走到黑。

我剛來的時候,見過一個global.css文件代碼有1000多行,現在它已經2000多行,接近3000行了,而且有好幾個版本。它的膨脹過程大致是這樣的:

一個新功能加進來,有一些公用樣式要加進去或是要修改,但是文件實在太大,注釋又不清楚,找不到原來的代碼,只好在文件的末尾添加新的樣式,提高權重覆蓋掉之前的樣式聲明。頁面一刷新,效果出來了,搞定!!!每次有功能修改或是新增,上面的過程就會重復一次。冗余代碼越來越多,文件越來越膨脹。

如果只看到上面兩點,不加思索的盲目推行重構,只是沿着前人走過的路再走一遍,新老員工一交替,我們這幫后人就會變成他們口中的前人,結果就是后人復怨后人矣!

稍作分析不難發現,對於css,我們不能按照功能或者業務來划分css模塊,為了減少請求,一個頁面所有的css樣式全部寫在一個文件里,后續即使有重大功能更新,也不會作新的版本,而是在原來的文件上增刪改,時間一長不敢刪和改了,只能增加覆蓋,結果就是冗余,耦合。對於js,我們雖然使用了seajs,但是沒有按照功能或者業務來划分模塊,只是用到了其處理依賴加載模塊的功能。

模塊化的意義

模塊化其實不僅僅是為了處理依賴,代碼復用。它更應該是一種分而治之的編程思想,每個獨立的功能或者業務划分為一個獨立的模塊,暴露的接口可以被應用程序調用,應用程序無需知道每個模塊的具體實現。我們現在對seajs的使用有點為了用而用的感覺,沒有解決問題。我常常能看到頁面里多個script標簽,各種模塊和非模塊化代碼雜亂無章寫在頁面里。

如何應用模塊化來重構

對於js,每個頁面應該只有一個入口模塊,其余的模塊組件都在該入口模塊內部實現依賴和加載,模塊應該按照功能或者業務來划分,原則上一個模塊,一個js文件。

這里有必要提到一個模板工具 artTemplate 以及為此開發的 編譯工具 Tmod,這兩個項目都已經在github上開源。

借助模板工具,我們可以不用在js里面用字符串拼接來生成DOM,讓js專心處理交互邏輯,保持代碼的可讀性和可維護性。

artTemplate 的好處在於,你可以把要插入的DOM直接寫入HTML文件而不是js文件,通過Tmod編譯工具自動編譯成js,並且支持cmd,amd輸出。看一個教育經歷模板的例子

教育經歷會有多條,它可以通過include 來引入單條教育經歷模板,編譯成js,輸出amd為自動為其處理依賴。輸出的js文件是這樣的(amd)

這個模塊的最后 return 一個 template()方法,參數是我們要注入的數據, 暴露了一個可以供外面調用的接口,調用十分方便

var eduTemplate = require('edulist'),    // 加載教育經歷模板
    
    eduContainer.html(eduTemplate(data));  // 傳入數據生成html代碼塊並且插入DOM

artTemplate 和 Tmod的地址在這里

對於css:

這里我想講一下sass, sass是css的一個預處理器(與之類似的還有less), 以及流行很多年了。

sass可以讓我們以寫js的方式來寫css,並且他支持引入局部文件,這里的局部文件我們可以當成sass模塊或者組件

sass的主要特點:

1、可以聲明變量,拿一個我們經常遇到的一個種場景:全站的按鈕的顏色要從淡綠色變成深綠色,css你需要一個個找到替換,如果是全部還好,可以用編輯器的全局替換,如果是部分,那就只能呵呵了。用sass, 你只需要聲明一個變量,給它賦值,以后所有的用到這個顏色的地方都使用這個變量,而不適用具體的顏色值。修改的時候只需要修改這個變量的值即可。

$globalBtnColor: lightgreen !default;

.btn1{
      background-color: $globalBtnColor; 
}
.btn2{
      background-color: $globalBtnColor; 
}

2、可以把一大段css樣式封裝成一個 mixin,要用的時候就可以像js函數一樣調用一下就可以了,下面寫一個清理浮動

@import "compass/reset";

@mixin clearfix($supportIe:false){
	@if ($supportIe){
		*zoom: 1;
	}
	&:after{
		content: '';
		display: block;
		clear: both;
	}
}

#wrapper{
	@include clearfix();
}

上面的代碼,clearfix還支持傳入參數,如果你要支持ie6, 可以傳入true,生成的css會有一個針對ie6的hack,該參數默認為false,既不支持ie6

3、可以引入局部文件,你可以把組件的樣式單獨寫在一個sass文件,要引入的時候只要 @import "yourfilename.scss"; 編譯之后的css文件就會包含組件的樣式

上面我引入了3個文件,global.scss , datePicker.scss , dialog.scss ; 分別將全局,時間組件, 彈窗組件的樣式引入, 編譯之后只有一個css文件, 無需理會css文件里的內容, 維護的時候只要維護對應的sass文件即可。

這樣,我們的css模塊化也就是可行的了, 我們可以把頁面上的css拆分成獨立的模塊, 頭部 header.scss,  尾部 footer.scss,  篩選 filter.scss. 最后在主題的sass文件中全部導入, 以后換了頭部 我們只要維護 header.scss文件即可, 分而治之的好處盡顯....

sass還有很多很強大的功能,不一一列舉,感興趣的童鞋可以google一下, 相關的文檔和社區都有很完善的使用指南。

使用模塊化必須要談的是構建,模塊化可以讓我們用單獨的文件來組織管理我們的代碼,但是如果不進行處理,就會造成頁面加載請求數量過多,頁面加載緩慢。通過構建可以將模塊打包成一個文件,並且實現代碼壓縮,減少體積。

常用的構建工具有:grunt(這貨我剛學會用它好像就已經過時了),gulp,webpeck....

 

最后...

前端是一個新的領域,也是一個快速發展(快的讓人蒙圈)的領域,有人提出了一個前端摩爾定理: 前端每18個月難一倍。不學習就會被甩掉好幾條街啊..

本人才疏學淺,有錯誤的地方還請指正

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM