前端架構(gòu)存在的目的,
1、提高代碼的可讀性。
一個(gè)好的架構(gòu),代碼的可讀性一定是強(qiáng)的。
簡(jiǎn)單來(lái)說(shuō),假如有一個(gè)新人加入團(tuán)隊(duì),那么他接手這個(gè)項(xiàng)目,一定是容易上手的,能簡(jiǎn)單輕松的了解整個(gè)前端部分的相互關(guān)系,從而找到自己需要重點(diǎn)關(guān)注的點(diǎn)。而不是需要花很多時(shí)間去熟悉這個(gè)項(xiàng)目的很多細(xì)節(jié),才能開(kāi)始上手做東西。
就文件來(lái)說(shuō),可以從文件名上,分清哪些是頁(yè)面、哪些是邏輯、哪些是樣式、哪些是可以復(fù)用的組件、哪些是圖標(biāo)組、又有哪些是移動(dòng)端或是PC端專享的樣式/邏輯等。
就代碼來(lái)說(shuō),包括統(tǒng)一的命名風(fēng)格,封裝在同一個(gè)文件里的代碼的相關(guān)性足夠強(qiáng)等。
2、提高代碼的可維護(hù)性。
一個(gè)好的架構(gòu),一定是易于維護(hù)的,例如在新增需求、更改需求、修正bug,都不會(huì)造成意料之外的變化,比如說(shuō)修改了一個(gè)頁(yè)面組件的內(nèi)容,卻導(dǎo)致另外一個(gè)頁(yè)面組件發(fā)生變化(這也太坑了)。
因此,要低耦合,高內(nèi)聚,以及輸入和輸出是可預(yù)期的。
3、提高代碼的可擴(kuò)展性。
一個(gè)好的架構(gòu),一定擴(kuò)展性要強(qiáng),不能寫(xiě)死。
需求變更太正常了,新增需求也太正常了。因此好的架構(gòu),必須要考慮到這些情況的發(fā)生,因?yàn)樗麄兪且欢〞?huì)發(fā)生的。所以,一定要避免把代碼寫(xiě)死。
比如頁(yè)面組件A里需要有一個(gè)日歷組件,而這個(gè)日歷組件引用的是別人的(比如從github上找的),那么盡量不要直接在頁(yè)面組件A里面直接引用這個(gè)日歷組件,而是將寫(xiě)一個(gè)日歷組件B,在這個(gè)日歷組件B里封裝你引用的日歷組件C,然后通過(guò)這個(gè)日歷組件B來(lái)進(jìn)行操作。
原因很簡(jiǎn)單,假如某天產(chǎn)品經(jīng)理說(shuō),這個(gè)日歷組件太丑了,我們換一個(gè)吧。如果你直接在頁(yè)面組件A里內(nèi)嵌這個(gè)引用的日歷組件C,你很可能就要改很多代碼(因?yàn)椴煌諝v組件的使用方法和暴露的接口可能不同)。假如你還在其他多個(gè)地方引用了這個(gè)日歷方都要改。
而若是將引用的日歷組件C封裝到自己寫(xiě)的日歷組件B之中,那么你只需要改日歷組件B里的相應(yīng)代碼即可,而因?yàn)槿諝v組件B暴露的接口是不變的,那么自然不用修改頁(yè)面中的代碼了。
4、便于協(xié)同。
包括前端和后端的協(xié)同,前端和前端之間的協(xié)同。
具體來(lái)說(shuō),前后端的協(xié)同通常是以ajax為交互,那么應(yīng)至少有一個(gè)用于專門(mén)封裝了所有ajax請(qǐng)求的文件,所有ajax請(qǐng)求都封裝在這里。在開(kāi)發(fā)時(shí),這里封裝的方法應(yīng)該可以模擬發(fā)送和接收約定好的交互內(nèi)容,方便開(kāi)發(fā)聯(lián)調(diào)。
而前端和前端的協(xié)同,主要體現(xiàn)在同時(shí)在更改代碼時(shí),不會(huì)影響對(duì)方代碼的正常運(yùn)行。因此要求封裝、解耦以及低干擾度是必須的。
5、自動(dòng)化
自動(dòng)打包,壓縮,混淆,如果有必要,再加上自動(dòng)單元測(cè)試。
前端架構(gòu)師們認(rèn)為有多個(gè)關(guān)鍵的決策需要在項(xiàng)目啟動(dòng)之初就制定下來(lái),如果等到開(kāi)發(fā)階段的后期再考慮,不是已經(jīng)用不上,而是一開(kāi)始錯(cuò)誤的決定已經(jīng)造成了無(wú)法挽回的損失。一旦做出這些決策,我們的任務(wù)就是去輔助視覺(jué)設(shè)計(jì)、平臺(tái)開(kāi)發(fā)、底層結(jié)構(gòu),使之能最大程度滿足需求,要做到以下幾點(diǎn);
模塊化標(biāo)記
我們都在追求的理想的狀態(tài)是,網(wǎng)站每一行HTML都由程序自動(dòng)生成,而作為前端開(kāi)發(fā)人員,我們只需要管理這個(gè)用來(lái)產(chǎn)生標(biāo)記的模板和流程,遺憾的是,現(xiàn)實(shí)通常并非如此。即使在最好的情況下,也存在用戶生成的內(nèi)容,而這些內(nèi)容幾乎都無(wú)法自動(dòng)添加CSS類名來(lái)標(biāo)記。無(wú)論CMS系統(tǒng)(可以理解為后臺(tái))自動(dòng)生成HTML的能力如何,讓CMS決定類似表單和導(dǎo)航欄這樣的標(biāo)記,有時(shí)候會(huì)更簡(jiǎn)單。
模塊化標(biāo)記和手寫(xiě)的靜態(tài)標(biāo)記的區(qū)別在于,程序化地執(zhí)行完之后,我們還可以通過(guò)一套類名系統(tǒng)給標(biāo)記動(dòng)態(tài)添加CSS類名。而且不再通過(guò)元素標(biāo)簽和層級(jí)關(guān)系來(lái)決定視覺(jué)外觀。讓我們看看如何用BEM原則(一個(gè)CSS規(guī)則,下面會(huì)說(shuō)到)模塊化地實(shí)現(xiàn)一個(gè)簡(jiǎn)單的導(dǎo)航:
<nav class="nav">
<ul class="nav__container">
<li class="nav__item">
<a href="/products" class="nav__link">
<ul class="nav__container--secondary">
<li class="nav__item--secondary">
<a href="/socks" class="nav__link--secondary">
要使用這種模塊化方法,我們首先需要改變構(gòu)建頁(yè)面的方法和思路。作為前端開(kāi)發(fā)人員,我們的工作就是把視覺(jué)語(yǔ)言拆解成最小單元,拆解之后,我們可以創(chuàng)建規(guī)則,對(duì)這些最小單元進(jìn)行重組。
上面提到的BEM(Block Element Modifier,塊元素修飾符)是一個(gè)CSS類名命名規(guī)則,它建議每個(gè)元素都添加帶有如下內(nèi)容的CSS類名:
塊名。所屬組件的名稱。
元素。元素在塊里面的名稱
修飾符。任何與塊或元素相關(guān)聯(lián)的修飾符
過(guò)多的CSS依賴
如果我們想渲染我們樣式中的某一塊內(nèi)容,首先需要加載以下內(nèi)容
Boostrap CSS: 114KB(未壓縮)。其實(shí)網(wǎng)站本身沒(méi)怎么調(diào)用Boostrap庫(kù)的代碼,但我們編寫(xiě)所有CSS的前提條件都是Boostrap已經(jīng)重置了基本樣式。
核心的網(wǎng)站CSS: 500KB。雖然一般來(lái)說(shuō),每塊內(nèi)容都有一個(gè)單獨(dú)的關(guān)聯(lián)文件。但這個(gè)文件不是這塊內(nèi)容的單一樣式來(lái)源。樣式不僅來(lái)源位置多樣,并且常?;谖恢煤晚?yè)面的類被覆蓋重寫(xiě)。
自上而下的樣式命名方法意味著,每次修改我們都要寫(xiě)一個(gè)更長(zhǎng)的、更具體的選擇器,同時(shí),因?yàn)闃?biāo)記順序極為嚴(yán)格,每塊內(nèi)容都很難重排或者替換。當(dāng)然我們可以抽出一個(gè)單獨(dú)文件,并把它需要的所有樣式合并到單獨(dú)的一個(gè)文件里,但是這么做基本意味著完全重做這個(gè)組件里的CSS文件,每塊內(nèi)容都很難重排或者替換。
因此我們指定了一些規(guī)則,以下是我們指定這些規(guī)則時(shí)需遵循的規(guī)范:
只包含不可變的規(guī)則,而不是籠統(tǒng)的說(shuō)明。
總是把規(guī)則提煉成最簡(jiǎn)單的表達(dá)。
總是首先說(shuō)明規(guī)則時(shí)什么,再說(shuō)明“如果不這樣,那么會(huì)怎么樣”
每個(gè)規(guī)則必須包含以下詞的一個(gè)——總是、永遠(yuǎn)不要、只有、每一個(gè)、不要、要
最后指定的設(shè)計(jì)系統(tǒng)的規(guī)則如下
永遠(yuǎn)不要給布局的子內(nèi)容強(qiáng)加內(nèi)邊距和元素樣式。布局只關(guān)注垂直對(duì)齊、水平對(duì)齊和文字間距。
主題和別的數(shù)據(jù)屬性值永遠(yuǎn)不要強(qiáng)制改變外觀,他們必須保持布局、組件和元素可以應(yīng)用于其上。
組件總是貼著它的父容器的四個(gè)邊,元素都沒(méi)有上外邊距和左外邊距、所有的最后節(jié)點(diǎn)(最右邊和最下邊的節(jié)點(diǎn))的外邊距都會(huì)被清楚。
組件本身永遠(yuǎn)不要添加背景、寬度、浮動(dòng)、內(nèi)邊距和外邊距的樣式,組件樣式是組件內(nèi)元素的樣式。
每個(gè)元素都有且只有一個(gè)唯一的且作用于只在組件內(nèi)的CSS類名,所有的樣式都是直接應(yīng)用到這個(gè)選擇器上, 并且只有上下文和主題能修改元素的樣式。
JavaScript
為js創(chuàng)建規(guī)范是非常有必要的,可以參考以下建議:
保持代碼整潔。JS Hint是這寫(xiě)工具中一個(gè)很好的例子,這里有幾條可以通過(guò)JS Hint檢查的規(guī)則:
強(qiáng)制使用===和!==代替==和!=
限制代碼塊嵌套深度
限制函數(shù)的參數(shù)數(shù)量
如果函數(shù)重復(fù)定義,發(fā)出警告
如果變量創(chuàng)建后未被使用,發(fā)出警告
創(chuàng)建可復(fù)用的函數(shù)。比如我們常用的addClass操作,如果需要多次創(chuàng)建新的.green-alert類名,只需要修改定義好的add_background方法:
$.fn.add_background = function(color){
this.css('background-color', color);
return this;
}
測(cè)試核心;
在開(kāi)始為應(yīng)用程序規(guī)劃測(cè)試時(shí),請(qǐng)記住以下幾條建議:
測(cè)試用例應(yīng)該在建站的同時(shí)或之前開(kāi)始編寫(xiě)
測(cè)試代碼是真實(shí)的代碼,應(yīng)該一起或立即提交到系統(tǒng)代碼庫(kù)中。
必須在所有的測(cè)試用例都通過(guò)之后,才能把代碼合并到主干上。
在主干上運(yùn)行測(cè)試工具,結(jié)果都應(yīng)該為通過(guò)。
單元測(cè)試時(shí)將應(yīng)用程序分解為盡可能小的函數(shù),并創(chuàng)建可重復(fù)的、自動(dòng)化的測(cè)試用例的過(guò)程。“一次只做一件事,并把它做好”是構(gòu)建基于單元測(cè)試的應(yīng)用程序的原則(函數(shù)式),我們?cè)趯?xiě)函數(shù)時(shí)經(jīng)常想同時(shí)實(shí)現(xiàn)很多功能,結(jié)果最后不僅降低了了效率,還增加了測(cè)試的難度。
單元測(cè)試的基本思路是調(diào)用要測(cè)試的函數(shù),傳遞一些預(yù)先設(shè)置好的參數(shù),并描述結(jié)果是什么。
function calculateShipping(distance){
switch(distance){
case(distance < 25):
shipping = 4;
break;
case(distance < 100):
shipping = 5;
break;
case(distance < 1000):
shipping = 6;
break;
return shipping;
}
}
QUnit.test('Calculate Shipping', function(assert){
文章內(nèi)容來(lái)源于網(wǎng)絡(luò),侵刪