天天看點

代碼美化的藝術

代碼美化的藝術
Ng-Matero 中文版文檔已經釋出 點選檢視

原本隻是想簡單的聊一下代碼格式化的問題,無奈本文拖沓了很久,在此期間,我又思考了很多,我越來越覺得代碼格式化是一門藝術。為了襯托“藝術”二字,可能叫“代碼美化”更貼切一點,但是本文的深度遠沒有标題那麼宏大。

在我看來,代碼品質不僅展現在邏輯上,也要展現在形式上。尤其前端代碼,在日漸複雜的單頁面開發中,代碼格式化不僅是為了美觀,也是為了更好的閱讀及檢查。關于代碼的格式化并沒有統一的标準,每個人都有自己的見解,是以本文的目的以探讨和推薦為主。

可能很少有人會去考慮這方面的問題,畢竟美化插件都是現成的,比如常用的 Prettier,隻要一個快捷鍵就可以迅速格式化,但是代碼格式化插件的标準并不一定是最好的。

本文範例主要以 Angular 為主,但是代碼美化的建議同樣适用于 React 和 Vue。

歡迎關注基于 Angular Material 的中背景管理架構 Ng-Matero

關于代碼字元數一直是一個争論不休的問題。在 Python編碼風格指導(PEP8) 規定了每行不超過 80 個字元。Prettier 預設也是 80 個字元。

贊成這條規範的人認為 80 個字元緊湊美觀,在大屏顯示器也可以分多欄顯示。如下圖所示:

代碼美化的藝術

我最開始也是贊成 80 個字元的建議,但是當我遵循這條規範寫了近一年的 Angular 代碼之後,我發現這條規範有一些缺陷。

首先這條規範是 Python 編碼風格的建議,而 Python 的代碼是以縮進代表代碼塊,類、函數等在定義時也沒有大括号及小括号,算上括号前的空格,這就比一般的代碼少幾個字元。

其次現代的程式設計模式大多是面向對象的風格,類的繼承、接口實作等都可能導緻代碼很長,在 Angular 中可能還會實作多個鈎子函數的接口。

另外,Angular 的風格指南建議不要為了精簡變量命名而損失易讀性,是以很多時候函數命名可能很長,再加上類型系統及鍊式調用等,單行代碼很容易超過 80 個字元,這樣就會造成過多的折行。

下面是一段使用 80 字元寬度格式化的 TS 代碼:

代碼美化的藝術

我們再看一下擴大到 100 字元之後的效果:

代碼美化的藝術

這段代碼或許還不是最典型的例子,但是也能看出兩者的不同,在實際的業務當中,類似的折行可能更多,而從我個人的角度來看,過多的折行反而破壞了代碼的完整度。目前常用的代碼寬度有三種,分别是 80、100、120,很顯然,80 太短,120 太長,以中庸之道,取 100 剛好。

代碼寬度對模闆(html)的影響也很大,下面我們重點聊一下關于模闆的格式化問題。以下是使用 Prettier 的預設設定格式化的效果。

代碼美化的藝術

上面這種格式化方案非常普遍,但是我個人并不喜歡這種格式化的效果,原因有以下幾點:

開始标簽末尾的尖括号看上去有點突兀。

所有屬性全部換行,整體有些松散,模闆代碼可能變得很長。

标簽和屬性的區分度不高。

我比較喜歡下面的格式化方案,整齊緊湊,屬性之間對齊,标簽一目了然。

代碼美化的藝術

簡單說一下上面這種格式化效果的方法:需要使用 VSCode 預設的 HTML 格式化插件。在 <code>首選項-設定-擴充-HTML</code>,設定 <code>Wrap Attributes</code> 屬性,選擇 <code>preserve-aligned</code>(保留屬性的包裝,但對齊),這個選項允許多個标簽單行顯示。

Prettier 好像無法實作(有了解的朋友可以留言)。

最近在格式化代碼的過程中,我總結了一套排序規則及格式化建議,大家可以參考一下。

給元素屬性排序是一個可有可無的操作,但是合理的屬性順序同樣有利于代碼的閱讀及檢查。這和排列 CSS 屬性順序幾乎是一樣的。在編寫 CSS 的時候,我會刻意的按照以下順序排列屬性:

Positioning

Box model

Typographic

Visual

Misc

詳情參考 Code Guide,以下是元素屬性排序建議:

模闆引用變量

class

結構型指令

屬性型指令

雙向綁定

屬性綁定

事件綁定

五個及五個以下屬性盡量不要強制換行

某些屬性建議放在一起,比如 <code>ngModel</code> 和 <code>name</code>,<code>label</code> 和 <code>value</code>

元素标簽盡量對齊(除單行元素外)

插值表達式盡量換行

和type 有關的屬性盡量前置

以下是根據以上規則格式化後的代碼

代碼美化的藝術

我覺得模闆和函數非常類似,模闆屬性就好比函數參數。如果使用 Prettier 進行格式化,函數字元超出限制之後,所有參數預設全部折行顯示,這種方式的潛在問題和模闆屬性折行的問題非常類似,我覺得函數參數如果也能用 <code>preserve-aligned</code> 可能會更好,但是 VSCode 無法做到這一點。

谷歌推薦 clang-format 進行格式化,初步試了一下,并沒有達到滿意的效果,可能配置檔案有點問題。我覺得關于函數的格式化問題暫時可以不必深究。

代碼美化隻是一種形式,它不會對邏輯産生任何影響,但是好的代碼格式會間接影響我們編碼的速度,甚至影響到代碼的品質。

本文篇幅有限,也有很多不當之處,如果讀者對代碼美化有更好的建議,歡迎留言評論。

代碼美化的藝術

感謝您的閱讀,如果您對我的文章感興趣,可以關注我的部落格,我是叙帝利,下篇文章再見!

開發低代碼平台的必備拖拽庫 https://github.com/ng-dnd/ng-dnd

基于 Angular Material 的中背景管理架構 https://github.com/ng-matero/ng-matero

Angular Material Extensions 擴充元件庫 https://github.com/ng-matero/extensions

仿 Windows 照片檢視器插件 https://github.com/nzbin/photoviewer

仿 Windows 照片檢視器插件 jQuery 版 https://github.com/nzbin/magnify

完美替代 jQuery 的子產品化 DOM 庫 https://github.com/nzbin/domq

簡化類名的輕量級 CSS 架構 https://github.com/nzbin/snack

與任意 UI 架構搭配使用的通用輔助類 https://github.com/nzbin/snack-helper

單元素純 CSS 加載動畫 https://github.com/nzbin/three-dots

有趣的 jQuery 卡片抽獎插件 https://github.com/nzbin/CardShow

懸疑科幻電影推薦 https://github.com/nzbin/movie-gallery

鍛煉記憶力的小程式 https://github.com/nzbin/memory-stake