Web 前端代碼規範 最後更新時間:2017-06-25 原始文章鏈接:https://github.com/bxm0927/web-code-standards 此項目用於記錄規範的、高可維護性的前端代碼,這是通過分析 Github 眾多前端代碼庫,總結出來的前端代碼書寫規範。 目錄 前端普適性規 ...
Web 前端代碼規範
最後更新時間:2017-06-25
原始文章鏈接:https://github.com/bxm0927/web-code-standards
此項目用於記錄規範的、高可維護性的前端代碼,這是通過分析 Github 眾多前端代碼庫,總結出來的前端代碼書寫規範。
目錄
License
public domain, Just take it.
Thanks
@Ruan YiFeng: https://github.com/ruanyf
@materliu:https://materliu.github.io/code-guide
@hzlzh: https://github.com/hzlzh/Front-End-Standards
@tguide: http://tguide.qq.com/main/base.htm
前端普適性規範
黃金定律
永遠遵循同一套編碼規範,可以是這裡列出的,也可以是你自己總結的。如果你發現本
規範中有任何錯誤,敬請指正。
不管有多少人共同參與同一項目,一定要確保每一行代碼都像是同一個人編寫的。
項目命名
項目名全部採用小寫方式,以中劃線分隔,禁止駝峰式命名。比如:my-project-name
文件命名
文件命名參照上一條規則,多個單片語成時,採用中劃線連接方式,比如說: error-report.html
有複數結構時,要採用複數命名法,比如說: scripts, styles, images, data-models
文件名中只可由小寫英文字母a~z、排序數字0~9或間隔符-組成,禁止包含特殊符號,比如空格、$等
為更好的表達語義,文件名使用英文名詞命名,或英文簡寫。
不允許命名帶有廣告等英文的單詞,例如ad,adv,adver,advertising,防止該模塊被瀏覽器當成垃圾廣告過濾掉。任何文件的命名均如此。
- index.shtml 引導頁&首頁
- main.shtml 首頁
- download.shtml 下載頁面
- act.html 活動列表頁面
- video.html 視頻
-
cdkey.html CDKEY頁面
-
base.css 基本樣式
- layout.css 框架佈局
- module.css 模塊樣式
- global.css 全局樣式
- font.css 字體樣式
- index.css 首頁樣式
- link.css 鏈接樣式
- print.css 列印樣式
HTML 規範
語法
使用四個空格的縮進,這是保證代碼在各種環境下顯示一致的唯一方式。
嵌套的節點應該縮進(四個空格)。
在屬性上,使用雙引號,不要使用單引號。
不要在自動閉合標簽結尾處使用斜線 - HTML5 規範 指出他們是可選的。
不要忽略可選的關閉標簽(例如, 和 </body>)。
![](images/logo.png)
HTML5 doctype
在每個 HTML 頁面開頭使用這個簡單地 doctype 來啟用標準模式,使其每個瀏覽器中儘可能一致的展現。
雖然doctype不區分大小寫,但是按照慣例,doctype大寫
<!DOCTYPE html>
語言屬性
<html lang="en">
</html>
字元編碼
通過明確聲明字元編碼,能夠確保瀏覽器快速並容易的判斷頁面內容的渲染方式。這樣
做的好處是,可以避免在 HTML 中使用字元實體標記(character entity),從而全部與
文檔編碼一致(一般採用 UTF-8 編碼)。
<meta charset="UTF-8">
IE 相容模式
IE 支持通過特定的 <meta> 標簽來確定繪製當前頁面所應該採用的 IE 版本。除非有強烈
的特殊需求,否則最好是設置為 edge mode,從而通知 IE 採用其所支持的最新的模
式。
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
響應式
<meta name="viewport" content="width=device-width, initial-scale=1">
引入 CSS 和 JavaScript
根據 HTML5 規範, 通常在引入 CSS 和 JavaScript 時不需要指明 type,因為 text/css 和 text/javascript 分別是他們的預設值。
<!-- External CSS -->
<link rel="stylesheet" href="code-guide.css">
<!-- In-document CSS -->
<style>
/* ... */
</style>
<!-- JavaScript -->
<script src="code-guide.js"></script>
實用高於完美
儘量遵循 HTML 標準和語義,但是不應該以浪費實用性作為代價。任何時候都要用儘量小的複雜度和儘量少的標簽來解決問題。
減少標簽數量
在編寫 HTML 代碼時,需要儘量避免多餘的父節點。很多時候,需要通過迭代和重構來使 HTML 變得更少。 參考下麵的示例:
<!-- Not so great -->
<span class="avatar">
![](...)
</span>
<!-- Better -->
![](...)
屬性順序
HTML 屬性應該按照特定的順序出現以保證易讀性。
- class
- id
- name
- data-*
- src, for, type, href, value , max-length, max, min, pattern
- placeholder, title, alt
- aria-*, role
- required, readonly, disabled
class 是為高可復用組件設計的,理論上他們應處在第一位。id 更加具體而且應該儘量少使用(例如, 頁內書簽),所以他們處在第二位。
Boolean 屬性
Boolean 屬性指不需要聲明取值的屬性。XHTML 需要每個屬性聲明取值,但是 HTML5 並不需要。
一個元素中 Boolean 屬性的存在表示取值 true,不存在則表示取值 false。
簡而言之,不要為 Boolean 屬性添加取值。
<input type="text" disabled>
JavaScript 生成標簽
在 JavaScript 文件中生成標簽讓內容變得更難查找,更難編輯,性能更差。應該儘量避免這種情況的出現。
CSS 規範
語法
使用四個空格的縮進,這是保證代碼在各種環境下顯示一致的唯一方式。
使用組合選擇器時,保持每個獨立的選擇器占用一行。
為了代碼的易讀性,在每個聲明的左括弧前增加一個空格。
聲明塊的右括弧應該另起一行。
每條聲明 : 後應該插入一個空格。
每條聲明應該只占用一行來保證錯誤報告更加準確。
所有聲明應該以分號結尾。雖然最後一條聲明後的分號是可選的,但是如果沒有他,你的代碼會更容易出錯。
逗號分隔的取值,都應該在逗號之後增加一個空格。
不要在顏色值 rgb() rgba() hsl() hsla()和 rect() 中增加空格,並且不要帶有取值前面不必要的 0 (比如,使用 .5 替代 0.5)。
所有的十六進位值都應該使用小寫字母,例如 #fff。因為小寫字母有更多樣的外形,在瀏覽文檔時,他們能夠更輕鬆的被區分開來。
儘可能使用短的十六進位數值,例如使用 #fff 替代 #ffffff。
為選擇器中的屬性取值添加引號,例如 input[type="text"]。 他們只在某些情況下可有可無,所以都使用引號可以增加一致性。
不要為 0 指明單位,比如使用 margin: 0; 而不是 margin: 0px;。
/* Bad CSS */
.selector, .selector-secondary, .selector[type=text] {
margin: 0px 0px 15px;
background-color: rgba(0, 0, 0, 0.5);
box-shadow: 0 1px 2px #CCC, inset 0 1px 0 #FFFFFF
}
/* Good CSS */
.selector,
.selector-secondary,
.selector[type="text"] {
margin-bottom: 15px;
background-color: rgba(0,0,0,.5);
box-shadow: 0 1px 2px #ccc, inset 0 1px 0 #fff;
}
聲明順序
相關的屬性聲明應該以下麵的順序分組處理:
- Positioning
- Box model 盒模型
- Typographic 排版
- Visual 外觀
Positioning 處在第一位,因為他可以使一個元素脫離正常文本流,並且覆蓋盒模型相關的樣式。盒模型緊跟其後,因為他決定了一個組件的大小和位置。
其他屬性只在組件內部起作用或者不會對前面兩種情況的結果產生影響,所以他們排在後面。
.declaration-order {
/* Positioning */
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 100;
/* Box-model */
display: block;
float: right;
width: 100px;
height: 100px;
/* Typography */
font: normal 13px "Helvetica Neue", sans-serif;
line-height: 1.5;
color: #333;
text-align: center;
/* Visual */
background-color: #f5f5f5;
border: 1px solid #e5e5e5;
border-radius: 3px;
/* Misc */
opacity: 1;
}
Don't use @import
與<link>
相比,@import
較慢,增加額外的頁面請求,並可能導致其他不可預見的問題。
<!-- Use link elements -->
<link rel="stylesheet" href="core.css">
<!-- Avoid @imports -->
<style>
@import url("more.css");
</style>
媒體查詢位置
儘量將媒體查詢的位置靠近他們相關的規則。不要將他們一起放到一個獨立的樣式文件中,或者丟在文檔的最底部。這樣做只會讓大家以後更容易忘記他們。這裡是一個典型的案例。
.element { ... }
.element-avatar { ... }
.element-selected { ... }
@media (min-width: 480px) {
.element { ...}
.element-avatar { ... }
.element-selected { ... }
}
首碼屬性
當使用廠商首碼屬性時,通過縮進使取值垂直對齊以便多行編輯。
/* Prefixed properties */
.selector {
-webkit-box-shadow: 0 1px 2px rgba(0,0,0,.15);
box-shadow: 0 1px 2px rgba(0,0,0,.15);
}
單條聲明的聲明塊
在一個聲明塊中只包含一條聲明的情況下,為了易讀性和快速編輯可以考慮移除其中的換行。所有包含多條聲明的聲明塊應該分為多行。
這樣做的關鍵因素是錯誤檢測 - 例如,一個 CSS 驗證程式顯示你在 183 行有一個語法錯誤,如果是一個單條聲明的行,那就是他了。在多個聲明的情況下,你必須為哪裡出錯了費下腦子。
.span1 { width: 60px; }
.span2 { width: 140px; }
.span3 { width: 220px; }
屬性簡寫
儘量不使用屬性簡寫的方式,屬性簡寫需要你必須顯式設置所有取值。常見的屬性簡寫濫用包括:
- padding
- margin
- font
- background
-border
-border-radius
大多數情況下,我們並不需要設置屬性簡寫中包含的所有值。例如,HTML 頭部只設置上下的 margin,所以如果需要,只設置這兩個值。過度使用屬性簡寫往往會導致更混亂的代碼,其中包含不必要的重寫和意想不到的副作用。
/* Bad example */
.element {
margin: 0 0 10px;
background: red;
background: url("image.jpg");
border-radius: 3px 3px 0 0;
}
/* Good example */
.element {
margin-bottom: 10px;
background-color: red;
background-image: url("image.jpg");
border-top-left-radius: 3px;
border-top-right-radius: 3px;
}
Less 和 Sass 中的嵌套
避免不必要的嵌套。可以進行嵌套,不意味著你應該這樣做。只有在需要給父元素增加樣式並且同時存在多個子元素時才需要考慮嵌套。
// Without nesting
.table > thead > tr > th { … }
.table > thead > tr > td { … }
// With nesting
.table > thead > tr {
> th { … }
> td { … }
}
代碼註釋
代碼是由人來編寫和維護的。保證你的代碼是描述性的,包含好的註釋,並且容易被他人理解。好的代碼註釋傳達上下文和目標。不要簡單地重申組件或者 class 名稱。
class 命名
保持 class 命名為全小寫,可以使用短劃線(不要使用下劃線和 camelCase 命名)。短劃線應該作為相關類的自然間斷。(例如,.btn 和 .btn-danger)。
避免過度使用簡寫。.btn 可以很好地描述 button,但是 .s 不能代表任何元素。
class 的命名應該儘量短,也要儘量明確。
使用有意義的名稱;使用結構化或者作用目標相關,而不是抽象的名稱。
命名時使用最近的父節點或者父 class 作為首碼。
使用 .js-* 來表示行為(相對於樣式),但是不要在 CSS 中包含這些 class。
選擇器
使用 class 而不是通用元素標簽來優化渲染性能。
避免在經常出現的組件中使用一些屬性選擇器 (例如,[class^="..."])。瀏覽器性能會受到這些情況的影響。
減少選擇器的長度,每個組合選擇器選擇器的條目應該儘量控制在 3 個以內。
只在必要的情況下使用後代選擇器 (例如,沒有使用帶首碼 classes 的情況).
代碼組織
以組件為單位組織代碼。
制定一個一致的註釋層級結構。
使用一致的空白來分割代碼塊,這樣做在查看大的文檔時更有優勢。
當使用多個 CSS 文件時,通過組件而不是頁面來區分他們。頁面會被重新排列,而組件移動就可以了。
編輯器配置
根據以下的設置來配置你的編輯器,將這些設置應用到項目的 .editorconfig 文件,來避免常見的代碼不一致和醜陋的 diffs。
- 使用四個空格的縮進。
- 在保存時刪除尾部的空白字元。
- 設置文件編碼為 UTF-8。
- 在文件結尾添加一個空白行。
JS 規範
語法
使用四個空格的縮進,這是保證代碼在各種環境下顯示一致的唯一方式。
聲明之後一律以分號結束, 不可以省略
完全避免 == != 的使用, 用嚴格比較條件 === !==
eval 非特殊情況, 禁用!!!
with 非特殊情況, 禁用!!!
單行長度,理論上不要超過80列,不過如果編輯器開啟"自動換行"的話可以不考慮單行長度
接上一條,如果需要換行,存在操作符的情況,一定在操作符後換行,然後換的行縮進4個空格
這裡要註意,如果是多次換行的話就沒有必要繼續縮進了,比如說下麵這種就是最佳格式。
if (typeof qqfind === "undefined" ||
typeof qqfind.cdnrejected === "undefined" ||
qqfind.cdnrejected !== true) {
url = "http://pub.idqqimg.com/qqfind/js/location4.js";
} else {
url = "http://find.qq.com/js/location4.js";
}
空行
方法之間加
單行或多行註釋前加
邏輯塊之間加空行增加可讀性
變數命名
標準變數採用駝峰標識
使用的ID的地方一定全大寫
使用的URL的地方一定全大寫, 比如說 reportURL
涉及Android的,一律大寫第一個字母
涉及iOS的,一律小寫第一個,大寫後兩個字母
常量採用大寫字母,下劃線連接的方式
構造函數,大寫第一個字母
var thisIsMyName;
var goodID;
var AndroidVersion;
var iOSVersion;
var MAX_COUNT = 10;
function Person(name) {
this.name = name
}
字元常量
一般情況下統一使用單引號
null的使用場景
初始化可能以後分配對象值的變數
與一個可能或可能沒有對象值的初始化變數進行比較
傳入一個預期對象的函數
從預期對象的函數返回
不適合null的使用場景
不要使用null來測試是否提供參數
不要測試值為null的未初始化變數
undefined使用場景
永遠不要直接使用undefined進行變數判斷
使用字元串 "undefined" 對變數進行判斷
// Bad
var person;
console.log(person === undefined); //true
// Good
console.log(typeof person); // "undefined"
對象字面量
// Bad
var team = new Team();
team.title = "AlloyTeam";
team.count = 25;
// Good
var team = {
title: "AlloyTeam",
count: 25
};
數組聲明
// Bad
var colors = new Array("red", "green", "blue");
var numbers = new Array(1, 2, 3, 4);
// Good
var colors = [ "red", "green", "blue" ];
var numbers = [ 1, 2, 3, 4 ];
單行註釋
雙斜線後,必須跟註釋內容保留一個空格
與下一行代碼縮進保持一致
可位於一個代碼行的末尾,雙斜線距離分號四個空格
// Good
if (condition) {
// if you made it here, then all security checks passed
allowed();
}
var zhangsan = "zhangsan"; // 雙斜線距離分號四個空格,雙斜線後始終保留一個空格
多行註釋格式
最少三行
前邊留空一行
/**
* 註釋內容與星標前保留一個空格
*/
何時使用多行註釋格式
難於理解的代碼段
可能存在錯誤的代碼段
瀏覽器特殊的HACK代碼
業務邏輯強相關的代碼
想吐槽的產品邏輯, 合作同事
文檔註釋
各類標簽 @param @method 等 參考 http://usejsdoc.org/
用於:方法、構造函數、對象
/**
* here boy, look here , here is girl
* @method lookGril
* @param {Object} balabalabala
* @return {Object} balabalabala
*/
括弧對齊
標準示例 括弧前後有空格,花括弧起始不另換行,結尾新起一行
花括弧必須要,即使內容只有一行
涉及 if for while do...while try...catch...finally 的地方都必須使用花括弧,即使內容只有一行
if else 前後留有空格
if (condition) {
doSomething();
} else {
doSomethingElse();
}
switch
switch和括弧之間有空格,case需要縮進,break之後跟下一個case中間留一個空白行
花括弧必須要, 即使內容只有一行。
switch 的 falling through 一定要有註釋特別說明,no default 的情況也需要註釋特別說明況
switch (condition) {
case "first":
// code
break;
case "second":
// code
break;
default:
// code
}
for
普通for迴圈, 分號後留有一個空格, 判斷條件等內的操作符兩邊不留空格
前置條件如果有多個,逗號後留一個空格
for-in 一定要有 hasOwnProperty 的判斷, 否則 JSLint 或者 JSHint 都會有一個 warn
for (i=0, len=values.length; i<len; i++) {
process(values[i]);
}
var prop;
for (prop in object) {
// 註意這裡一定要有 hasOwnProperty 的判斷, 否則 JSLint 或者 JSHint 都會有一個 warn !
if (object.hasOwnProperty(prop)) {
console.log("Property name is " + prop);
console.log("Property value is " + object[prop]);
}
}
變數聲明
所有函數內變數聲明放在函數內頭部,只使用一個 var(多了JSLint報錯), 一個變數一行, 在行末跟註釋, 註釋啊,註釋啊,親
函數聲明
一定先聲明再使用, 不要利用 JavaScript engine的變數提升特性, 違反了這個規則 JSLint 和 JSHint都會報 warn
function declaration 和 function expression 的不同,function expression 的()前後必須有空格,而function declaration 在有函數名的時候不需要空格,沒有函數名的時候需要空格。
函數調用括弧前後不需要空格
立即執行函數的寫法, 最外層必須包一層括弧
"use strict" 決不允許全局使用, 必須放在函數的第一行, 可以用自執行函數包含大的代碼段, 如果 "use strict" 在函數外使用, JSLint 和 JSHint 均會報錯
function doSomething(item) {
// do something
}
var doSomething = function (item) {
// do something
}
// Good
doSomething(item);
// Bad: Looks like a block statement
doSomething (item);
// Good
(function() {
"use strict";
function doSomething() {
// code
}
})();