我們應該如何編寫高質量的前端程式碼

前端小時發表於2020-04-04

編寫高質量程式碼是每一個程式設計師必備的技能之一,可以有效地進行專案的維護以及專案的合作開發

我們應該如何編寫高質量的前端程式碼

01 前言


這要從很久的事情開始說起,前端最初的發展就像一團渾濁的雲團,什麼都往一塊寫,然後東拼西湊,最後竟然能執行。其實每個人前端人都會對頁面的混雜感到頭疼,誰不想好好優化一下呢?但是奈何那會沒有成型的工具,更沒有現在高質量的元件庫,從此解放了我們的程式碼編寫,真正做到了開箱即用,它不香嗎?

從最初發展到現在,程式碼無非就是進行了高度的解耦,讓每一個部分都負責自己的內容,把結構、樣式與行為分離,使得程式碼的職能非常清晰,看什麼都舒服。所以後來很多前端都要求把自家的網站進行重構,畢竟誰也不想接手上一代遺留下來的產品,自己重新寫一套都比他們的要舒服。

02 程式碼維護難點


為什麼說前端的程式碼難以維護呢?其實主要是出於以下的三點:

瀏覽器層面

瀏覽器是我們前端人經常打交道的工具,其實是瀏覽器孕育了前端這個大家庭,也是我們生存的根本。假如使用者不需要看東西,不需要進行互動,或者我們就不需要存在了。不知道大家是否瞭解過全息投影?等到那項技術普及的時候,我們又是做著什麼樣的工作呢?

雖然現在瀏覽器的相容性越來越好,主流的瀏覽器一般都會相容很多css屬性,最起碼常用的、多人使用的你是一定要支援的,像flex佈局這種神仙屬性。當我們習慣於使用某一個瀏覽器(如谷歌)之後,再嘗試使用360瀏覽器,你會發現自己根部看不下去。就像你習慣於使用谷歌搜尋,但是要你使用百度一樣的道理。

所以前端瀏覽器之間的相容是我們必須要跨過的一道坎,即使現在的相容性越來越好,但是使用者群體也有很多使用IE或者360瀏覽器的,我們也不能忽略他們的使用。可是有一句話說,相容IE就是浪費生命,自己細品一下。

技術層面

由於每一家的公司使用的技術都不太一樣,事實上很多公司都會有自己內部的框架,我們要使用他們內部的框架與現有的技術框架結合在一起,那也是一件很頭疼的事情。即使你是一位剛跳槽進來的員工,也是要學習他們內部的技術框架你才可以進行專案的開發。

很多公司創立階段的時候可能vue、react等神仙框架還沒出來,就是jQuery的天下,我們的專案底層也不是一朝一夕就能改變的,所以很多公司即使知道了新技術的出現,也不會去使用,也是處於探索階段。假設公司需要使用一種新技術進行程式碼的重構,也可能因為員工對新技術的理解還不夠深刻,寫出的程式碼也會存在一定的設計漏洞。所以理解不深,就很容易寫出難以維護的程式碼,給我們的團隊造成閱讀困難,最終也會變成一個難以維護的專案。

團隊合作

團隊合作才是真正的難題,不像我們自己編寫的專案,想怎麼寫都行,不怕有看不懂的時候。當我們提交程式碼的時候也是不用經過其他成員的同意,直接push到master分支。這些都是我們個人開發的時候做法,到了公司層面或者專案的層面,那你就直接收拾東西吧。

大型的專案一般開發人員是比較多的,每一個人都會負責不同的模組和不同的功能,每一個人都會有自己獨立的分支,程式碼合併到主分支的時候還得經過稽核,這是一個完善、系統的開發流程。所以專案越複雜,團隊合作的要求就會越高。一般我們都會有一種程式碼開發規則,大家都應該相互遵守,不然我們就會汙染正常的程式碼,導致專案難以維護。所謂團隊合作的最大困難不是技術,是人。

小結:

除了我們要專案的程式碼進行解耦,把結構、樣式與行為進行分離之外,我們還應該重視簡潔、可複用以及結構化的特點。當你能夠做到這些的時候,你的專案就會顯得專業,程式碼的可維護性以及可擴充套件性就會越高,開發人員新增新的功能或者模組就會顯得比較輕鬆。

03 高質量結構程式碼


語義化

HTML5出來之後,新增了很多新的標籤和屬性,而語義化這個概念就出現在前端人的眼中。之前我們編寫結構程式碼的時候一般會選擇使用div與類名/ID名的方式來命名一個模組,所謂DIV+CSS開發模式就是這樣由來。那麼這種方式可否可行呢?當然是可行的,而且別人用的很舒服,就是cv操作多了點。

當然缺點是有的,比如最主要的就是結構不清晰,無論是編寫導航還是模組、亦或是底部,全程div。這樣結構就不清晰了,如果沒有加以類名或者ID名,根本不知道你寫的程式碼是屬於哪一個模組。而且還有一點就是對搜尋引擎不友好,不能準確識別你的網站結構和資訊。

那麼如何看你的程式碼是否語義化呢?很簡單,把所有的樣式都去掉,看你的頁面結構是否顯示正常,一般語義化的標籤都會有預設的樣式。如果顯示還可以,結構有序就是語義化比較好了,反之你就重新寫一下吧。

模組化

模組化其實就是跟在語義化之後的,如果你的語義化做的比較好,那麼相應的模組化就比較好了。我認為模組化的重點應該關注你的標籤選擇是否合理,比如文字就使用p/span標籤,標題應該使用H1-6標籤等。不能所有的文字都是用div這個萬能的標籤元素,能用p的就不要去用div,因為p本身是針對文字的,有一定的基礎樣式。

小結:

不過現在我們似乎不會關注這些東西了,因為有了高顏值元件庫的出現,需要什麼直接cv過來使用。但是我們注意的是,並不是說這樣你就逃避學習的理由,因為無論是多高大上的元件都是由最基本的樣式和結構組成的,學會背後的造輪子思想才是最重要的。當元件不能滿足業務上的需求的時候,就需要你進行css程式碼的編寫了。

04 高質量樣式程式碼


盒子模型

一般面試或多或少都會問一下你關於css盒子模型的理解,如果沒有準備的小夥伴可能會把內容搞混了。這裡再重複一遍:

  • IE:元素的寬度由width+border+padding組成
  • 標準:元素的寬度就是width,本身包括了padding+border
樣式組織

關於我們頁面的樣式如何編寫,也是我們要考慮的一個問題,我們關於樣式的編寫沒有對錯只有好壞。頁面寫出來,能夠滿足自己的期望那就是對的樣式,是否合理又是另一方面的事情了。

所以這裡可以參考一下樣式的結構組織:reset.css+common.css+view.css

首先第一個是基本的樣式標準,專注於底層的樣式。這裡的reset是指我們把瀏覽器預設的基本樣式都重置一下,儘量滿足所有的瀏覽器樣式看起來是一致的。還記得我們之前說過萬用字元*嗎?那是一個及其暴力的樣式重置,但也是很危險的一個操作符。危險是因為需要遍歷頁面所有的元素節點,給他加上樣式。這裡我們就推薦使用網上的reset.css即可,都有很多供你選擇,假如你懶得找且專案支援npm安裝,直接npm i reset-css即可,簡單快速方便。

common.css是指一些元件相關的樣式,比如我們們如果在vue裡面寫程式碼的話就知道一個vue檔案可以由三部分組成,其中一個部分就是可以讓你編寫屬於元件的樣式程式碼,這裡我們重用元件的時候就會顯得非常方便。關於view.css其實就是一個更高層次的編寫,屬於一個頁面的樣式檔案。

選擇器使用

選擇器可對某一個節點進行樣式編寫,有同學可能會說,我能把我的節點樣式應用成功就好,還需要關心它怎麼使用嗎?其實要的,我們先從css選擇器的匹配方案說起,選擇器是從右向左進行匹配的,.class ul li a p這樣的選擇器,會先從全域性匹配p標籤然後再匹配a標籤,依次類推。

所以第一個問題就是我們一定要避免選擇器的巢狀過深,因為很耗費效能。假如可以使用ID匹配到唯一的元素就不用使用其他的選擇器了。也正是因為選擇器的這種匹配規則,使得元素更高效的匹配,也是經過長期的驗證得來的結論。最後我們應該更加註意樣式的繼承,避免多次編寫重複樣式,所謂少用組合,多用繼承原則。

近年來出現的css前處理器可以有效地提高樣式的編寫,使用一種物件導向的寫法,更大程度對樣式程式碼進行復用,有stylus、scss、less等,讀者可以自行去官網瞭解。

編碼風格

樣式風格:關於css的編碼風格也是因人而異,一般來說我們應該使用多行的寫法,因為這樣可讀性就更高。假如樣式程式碼寫在一行,難免造成閱讀困難的情況。後期我們進行專案釋出的時候可以進行對程式碼的壓縮。

id/class:id選擇器一般使用在全域性唯一的元素節點上面,如果確定元素節點唯一的情況下我們就可以使用,但是假如元素節點不唯一,那麼就推薦使用class。

05 高質量的行為程式碼


良好習慣

因為專案涉及到多人開發,每個人自己使用的變數應該自己來維護,這樣可以有效避免程式碼衝突,覆蓋正常的程式碼等。所以我們應該禁止直接在全域性的作用域下進行程式碼的編寫,這樣很容易對別人的專案模組造成影響。那麼我們的避免的方法有哪些呢?

  • 團隊合作避免衝突

我們把自己的程式碼寫在一個匿名函式裡面,如(function(){})(),這樣程式碼裡面的變數就不會是全域性的了,而是屬於這個函式的內部變數,不會對他人的程式碼造成影響。用匿名的方式把程式碼包裹起來,可以有效控制全域性變數,避免衝突隱患。

  • 統一入口

我們還可以給函式一個統一的入口載入檔案,可以選擇函式入口為init,這樣所有初始化的操作都會在這裡進行。通過這樣我們就可以模擬DOMReady的事件了。

  • CSS放在頭部,JS放在底部

這個操作應該是每個人都應該遵循的做法,這樣更有利於瀏覽器頁面的載入優化,減少頁面空白的時間,提升使用者體驗。

JS分層

其實這裡的分層和css的分層道理是一樣的,也可以參考base層、common層、以及view層的形式。其中base層可以封裝不同瀏覽器的差異,提供統一的介面,完成一些相容的工作。common層提供可複用的元件,功能是給view層提供元件。common層和base層都可以為view層提供元件,不同的是common層可以提供更龐大的元件。比如一些拖拽功能的實現等。關於view層就是直接對前兩層的呼叫,這裡是關於頁面邏輯的實現部分,如進行介面的請求等與具體功能需求相關的操作。

實用技巧
  • 彈性

彈性是指我們能夠輕鬆應對客戶提出來的需求,不用每新增一個需求就修改一些js程式碼,這是很不方便的事情。比如像事件代理一樣,可以實現一些精簡的操作,不用每新增一個節點就手動新增事件的監聽函式。

  • 可複用性

現在基本上我們實現什麼的功能都要先考慮一下如何才可以把寫的程式碼進行復用,以減少一些業務相關或功能相關的程式碼,做到一次編寫,到處可用。能夠公用且不影響元件之間的功能就是我們的追求。實現的方法我們可以通過傳參的形式來進行。

  • 避免副作用

我們開發的基礎程式碼可能能夠滿足我們目前的需求,但也可能我們在使用的過程當中產生了一些副作用不是我們想要的,為了避免這個問題,我們應該考慮一下是否我們的函式耦合性太高,考慮解耦等。

06 小結


今天就和大家聊一下關於編寫高質量的程式碼的事情,其實還有很多方面來不及編寫,讀者自己也可以自行查閱相關資料。主要是從結構、樣式以及行為三個方面來進行講解,這也是對應著我們前端的基本語言html,css以及js。

結構方面我們說了語義化編寫和模組化編寫,樣式方面我們說了盒子模型,樣式的編寫、樣式風格和選擇器的使用等,行為方面我們說了關於編寫的良好習慣,js分層等。

其實具體的實現還得大家自己進行感悟,這些都是前人總結下來的經驗而已,專案之中的具體細節可以依據以上的規則來進行編寫,相信應該會提升一個程式碼質量層級。

參考書籍

  • 編寫高質量程式碼——web前端修煉之道

我們應該如何編寫高質量的前端程式碼

相關文章