首次發(fā)表在個(gè)人博客
前言
程序語(yǔ)言的編碼風(fēng)格指南對(duì)于一個(gè)長(zhǎng)期維護(hù)的軟件而言是非常重要的;好的編程風(fēng)格有助于寫(xiě)出質(zhì)量更高、錯(cuò)誤更少、更易于 維護(hù)的程序。
團(tuán)隊(duì)合作需要制定一些代碼規(guī)范還有利用一些工具來(lái)強(qiáng)制要求團(tuán)隊(duì)代碼的風(fēng)格統(tǒng)一.畢竟很多情況下以后不一定是由寫(xiě)一手代碼的人來(lái)維護(hù)代碼,所以有一個(gè)統(tǒng)一的代碼風(fēng)格很重要!!!
最近看了一下編寫(xiě)可維護(hù)的JavaScript和編寫(xiě)高質(zhì)量代碼:Web前端開(kāi)發(fā)修煉之道,根據(jù)書(shū)中提倡的一些寫(xiě)法,同時(shí)結(jié)合我個(gè)人的經(jīng)驗(yàn)和喜好做了一些改動(dòng),大致整理了如下JavaScript編碼風(fēng)格
JavaScript編碼風(fēng)格
1.縮進(jìn)
每一行的層級(jí)由4個(gè)空格組成,避免使用制表符(Tab)進(jìn)行縮進(jìn)
if (true) {
doSomething();
}
2.行的長(zhǎng)度
每行長(zhǎng)度不應(yīng)該超過(guò)80個(gè)字符.如果一行多于80個(gè)字符,應(yīng)當(dāng)在一個(gè)運(yùn)算符(逗號(hào),加好等)后換行.下一級(jí)應(yīng)當(dāng)增加兩級(jí)縮進(jìn)(8個(gè)字符).
// 好的寫(xiě)法
doSomething(arg1, arg2, arg3, arg4,
arg5);
// 不好的寫(xiě)法: 第二行只有4個(gè)空格的縮進(jìn)
doSomething(arg1, arg2, arg3, arg4,
arg5);
// 不好的寫(xiě)法: 在運(yùn)算符之前換行
doSomething(arg1, arg2, arg3, arg4
,arg5);
3.原始值
特殊值null除了下述情況應(yīng)當(dāng)避免使用
- 用來(lái)初始化一個(gè)變量,這個(gè)變量可能被賦值為一個(gè)對(duì)象
- 用來(lái)和一個(gè)已經(jīng)初始化的變量比較,這個(gè)變量可以是也可以不是一個(gè)對(duì)象
- 當(dāng)函數(shù)的參數(shù)期望是對(duì)象時(shí),被用作返回值傳出
// 好的做法
const person = null;
判斷一個(gè)變量是否定義應(yīng)當(dāng)使用 typeof 操作符
// 好的寫(xiě)法
if (typeof constiable == 'undefined') {
// do something
}
// 不好的寫(xiě)法
if (constiable == 'undefined') {
// do something
}
4.運(yùn)算符間距
二元運(yùn)算符前后必須使用一個(gè)空格來(lái)保持表達(dá)式的整潔.操作符包括賦值運(yùn)算符和邏輯運(yùn)算符
// 好的寫(xiě)法
const found = (values[i] === item);
// 不好的寫(xiě)法: 丟失了空格
const found = (values[i]===item);
// 好的寫(xiě)法
if (found && (count > 10)) {
doSomething();
}
// 不好的寫(xiě)法: 丟失了空格
if (found&&(count>10)) {
doSomething();
}
// 好的寫(xiě)法
for(let i = 0; i < count; i++) {
process(i);
}
// 不好的寫(xiě)法: 丟失了空格
for(let i=0; i<count; i++) {
process(i);
}
5.括號(hào)間距
當(dāng)使用括號(hào)時(shí),緊接左括號(hào)之后和緊接右括號(hào)之前不應(yīng)該有空格
// 好的寫(xiě)法
const found = (values[i] === item);
// 不好的寫(xiě)法: 左括號(hào)之后有額外的空格
const found = ( values[i] === item);
// 好的寫(xiě)法
if (found && (count > 10)) {
doSomething();
}
// 不好的寫(xiě)法: 右括號(hào)之后有額外的空格
if (found && (count > 10) ) {
doSomething();
}
// 好的寫(xiě)法
for(let i = 0; i < count; i++) {
process(i);
}
// 不好的寫(xiě)法: 參數(shù)兩邊有額外的空格
for(let i = 0; i< count; i++) {
process( i );
}
6.對(duì)象直接量
對(duì)象直接量應(yīng)當(dāng)使用如下格式
- 起始左花括號(hào)應(yīng)當(dāng)同表達(dá)式保持同一行
- 每個(gè)屬性的名值對(duì)應(yīng)當(dāng)保持一個(gè)縮進(jìn),第一個(gè)屬性應(yīng)當(dāng)在左花括號(hào)后另起一行.
- 每個(gè)屬性的名值對(duì)應(yīng)當(dāng)使用不含引號(hào)的屬性名,其后緊跟一個(gè)冒號(hào)(之前不含空格),而后是值
- 倘若屬性值是函數(shù)類(lèi)型,函數(shù)體應(yīng)當(dāng)在屬性名之下另起一行,而且其前后均應(yīng)保留一個(gè)空行
- 一組相關(guān)的屬性前后可以插入空行以提高代碼的可讀性
- 結(jié)束的右花括號(hào)應(yīng)當(dāng)獨(dú)占一行
// 好的寫(xiě)法
const object = {
key1: value1,
key2: value2,
func: function() {
},
key3: value3,
};
// 不好的寫(xiě)法: 不恰當(dāng)?shù)目s進(jìn)
const object = {
key1: value1,
key2: value2,
};
// 不好的寫(xiě)法:函數(shù)體缺少空行
const object = {
key1: value1,
key2: value2,
func: function() {
},
key3: value3,
};
當(dāng)對(duì)象字面量作為函數(shù)參數(shù)時(shí),如果值是變量,起始花括號(hào)應(yīng)當(dāng)同函數(shù)名在同一行.所有其余先前列出的規(guī)則同樣適用
// 好的寫(xiě)法
doSomething({
key1: value1,
key2: value2,
});
// 不好的寫(xiě)法
doSomething({ key1: value1, key2: value2 });
7.注釋
頻繁地適用注釋有助于他人理解你的代碼.如下情況應(yīng)當(dāng)使用注釋
- 代碼晦澀難懂
- 可能被誤認(rèn)為錯(cuò)誤的代碼
- 必要但不明顯的針對(duì)特定瀏覽器的代碼
- 對(duì)于對(duì)象,方法或者屬性,生成文檔是有必要的(使用恰當(dāng)?shù)奈臋n注釋).
1).單行注釋
使用單行注釋當(dāng)用來(lái)說(shuō)明一行代碼或者一組代碼.單行注釋可能有三種使用方式
- 獨(dú)占一行的注釋,用來(lái)解釋下一行代碼
- 在代碼行的尾部的注釋,用來(lái)解釋它之前的代碼
- 多行,用來(lái)注釋掉一個(gè)代碼塊
// 好的寫(xiě)法
if (condition) {
// 如果代碼執(zhí)行到這里,則說(shuō)明通過(guò)了所有的安全性檢測(cè)
allowed();
}
// 不好的寫(xiě)法:注釋之前沒(méi)有空行
if (condition) {
// 如果代碼執(zhí)行到這里,則說(shuō)明通過(guò)了所有的安全性檢測(cè)
allowed();
}
// 不好的寫(xiě)法: 錯(cuò)誤的縮進(jìn)
if (condition) {
// 如果代碼執(zhí)行到這里,則說(shuō)明通過(guò)了所有的安全性檢測(cè)
allowed();
}
// 不好的寫(xiě)法: 這里應(yīng)當(dāng)用多行注釋
// 接下來(lái)的這段代碼非常難, 那么,讓我詳細(xì)的解釋一下
// 1. xxxx
// 2. xxxx
if (condition) {
// 如果代碼執(zhí)行到這里,則說(shuō)明通過(guò)了所有的安全性檢測(cè)
allowed();
}
對(duì)于代碼行尾單行注釋的情況,應(yīng)確保代碼結(jié)尾同注釋之間至少一個(gè)縮進(jìn)
// 好的寫(xiě)法
const result = something + somethingElse; // somethingElse will never be null
// 不好的寫(xiě)法: 代碼和注釋間沒(méi)有足夠的空格
const result = something + somethingElse;// somethingElse will never be null
注釋一個(gè)代碼塊時(shí)在連續(xù)多行使用單行注釋是唯一可以接受的情況.多行注釋不應(yīng)當(dāng)在這種情況下使用
// 好的寫(xiě)法
// if(condition) {
// doSomething();
// }
2).多行注釋
多行注釋?xiě)?yīng)當(dāng)在代碼需要更多文字去解釋的時(shí)候使用.每個(gè)多行注釋都至少有如下三行.
1.首行僅僅包括 /* 注釋開(kāi)始.該行不應(yīng)當(dāng)有其他文字
2.接下來(lái)的行以 * 開(kāi)頭并保持左對(duì)齊.這些行可以由文字描述
3.最后一行以 */開(kāi)頭并同先前行保持對(duì)齊.也不應(yīng)當(dāng)有其他文字
多行注釋的首行應(yīng)當(dāng)保持同它描述代碼的相同層次的縮進(jìn).后續(xù)的每行應(yīng)當(dāng)有同樣層次的縮進(jìn)并附加一個(gè)空格(為了適當(dāng)保持 * 字符的對(duì)齊).每一個(gè)多行代碼之前應(yīng)當(dāng)預(yù)留一個(gè)空格
// 好的寫(xiě)法
if (condition) {
/*
* 如果代碼執(zhí)行到這里
* 說(shuō)明通過(guò)了所有的安全性檢測(cè)
*/
allowed();
}
// 不好的寫(xiě)法: 注釋之前無(wú)空行
if (condition) {
/*
* 如果代碼執(zhí)行到這里
* 說(shuō)明通過(guò)了所有的安全性檢測(cè)
*/
allowed();
}
// 不好的寫(xiě)法: 星號(hào)后沒(méi)有空格
if (condition) {
/*
*如果代碼執(zhí)行到這里
*說(shuō)明通過(guò)了所有的安全性檢測(cè)
*/
allowed();
}
// 不好的寫(xiě)法: 錯(cuò)誤的縮進(jìn)
if (condition) {
/*
* 如果代碼執(zhí)行到這里
* 說(shuō)明通過(guò)了所有的安全性檢測(cè)
*/
allowed();
}
// 不好的寫(xiě)法: 代碼尾部注釋不要用多行注釋格式
const result = something + somethingElse; /* somethingElse 不應(yīng)當(dāng)取值為null */
3)注釋聲明
注釋有時(shí)候可以用來(lái)給一段代碼聲明額外的信息.這些聲明的格式以單個(gè)單詞打頭并緊跟一個(gè)雙引號(hào).可使用的聲明如下
- TODO: 說(shuō)明代碼還未完成.應(yīng)當(dāng)包含下一步要做的事情
- HACK: 表明代碼實(shí)現(xiàn)走了一個(gè)捷徑
- XXX: 說(shuō)明代碼是有問(wèn)題的并應(yīng)當(dāng)盡快修復(fù)
- FIXME: 說(shuō)明代碼是有問(wèn)題的并應(yīng)當(dāng)盡快修復(fù).重要性略次于XXX
- REVIEW: 說(shuō)明代碼任何可能的改動(dòng)都需要評(píng)審
這些聲明可能在一行或多行注釋中使用,并且應(yīng)當(dāng)遵循同一般注釋類(lèi)型相同的格式規(guī)則
// 好的寫(xiě)法
// TODO: 我希望找到一種更快的方式
doSomething();
// 不好的寫(xiě)法: 注釋聲明空格不正確
// TODO : 我希望找到一種更快的方式
doSomething();
// 好的寫(xiě)法
// REVIEW: 有更好的方法嗎?
doSomething();
// 不好的寫(xiě)法: 代碼和注釋?xiě)?yīng)當(dāng)保持同樣的縮進(jìn)
// REVIEW: 有更好的方法嗎?
doSomething();
8.命名
變量命名應(yīng)當(dāng)采用駝峰命名格式,首字母小寫(xiě),每個(gè)單詞首字母大寫(xiě).變量名的第一個(gè)單詞應(yīng)當(dāng)是一個(gè)名詞(而非動(dòng)詞)比避免同函數(shù)混淆.不要在變量名中使用下劃線
// 好的寫(xiě)法
const myName = 'Jack';
// 不好的寫(xiě)法: 大寫(xiě)字母開(kāi)頭
const MyName = 'Jack';
// 不好的寫(xiě)法: 動(dòng)詞開(kāi)頭
const getMyName = 'Jack';
// 不好的寫(xiě)法: 使用下劃線
const my_name = 'Jack';
函數(shù)命名應(yīng)當(dāng)采用駝峰命名格式.函數(shù)名的第一個(gè)單詞應(yīng)當(dāng)是動(dòng)詞(而非名詞)來(lái)避免同變量混淆.函數(shù)名中最好不要使用下劃線.
// 好的寫(xiě)法
function doSomething() {
// 代碼
}
// 不好的寫(xiě)法: 大寫(xiě)字母開(kāi)頭
function DoSomething() {
// 代碼
}
// 不好的寫(xiě)法: 名詞開(kāi)頭
function car() {
// 代碼
}
// 不好的寫(xiě)法: 使用下劃線
function do_something() {
// 代碼
}
構(gòu)造函數(shù)--通過(guò)new元素安撫創(chuàng)建新對(duì)象的函數(shù)--也應(yīng)使用駝峰合適命名,首先首字母大寫(xiě).構(gòu)造函數(shù)命名應(yīng)當(dāng)以非動(dòng)詞開(kāi)頭,因?yàn)閚ew代表著創(chuàng)建一個(gè)對(duì)象實(shí)例的操作
// 好的寫(xiě)法
function MyObject() {
}
// 不好的寫(xiě)法: 小寫(xiě)字母開(kāi)頭
function myObject() {
}
// 不好的寫(xiě)法: 使用下劃線
function My_Object() {
}
// 不好的寫(xiě)法: 動(dòng)詞開(kāi)頭
function getMyObject() {
}
常量(不會(huì)被改變的變量)的命名應(yīng)當(dāng)是所有字母大寫(xiě),不同單詞之間用單個(gè)下劃線隔開(kāi).ES6中使用const來(lái)聲明一個(gè)常量
// 好的寫(xiě)法
const TOTAL_COUNT = 10;
// 不好的寫(xiě)法
const totalCount = 10;
// 不好的寫(xiě)法: 混合模式
const total_COUNT = 10;
對(duì)象的屬性同變量的命名規(guī)范相同.對(duì)象的方法同函數(shù)的命名規(guī)則相同.如果屬性或者方法是私有的,應(yīng)當(dāng)在之前加一個(gè)下劃線
// 好的寫(xiě)法
const object = {
_count: 10,
_getCount: function() {
return this._count;
}
}
9.賦值
當(dāng)給變量賦值時(shí),如果右側(cè)是含有比較語(yǔ)句的表達(dá)式,需要用圓括號(hào)包裹
// 好的寫(xiě)法
const flag = (i < count);
// 不好的寫(xiě)法:遺漏圓括號(hào)
const flag = i < count;
10.等號(hào)運(yùn)算符
使用 === (嚴(yán)格相等) 和 !==(嚴(yán)格不相等)代替 ==(相等) 和 !=(不等) 來(lái)避免弱類(lèi)型轉(zhuǎn)換錯(cuò)誤
// 好的寫(xiě)法
const same = (a === b);
// 不好的寫(xiě)法: 使用 ==
const same = (a == b);
11.三元操作符
三元運(yùn)算符應(yīng)當(dāng)僅僅用在條件賦值語(yǔ)句中,而不要作為if語(yǔ)句的替代品.
// 好的寫(xiě)法
const value = condition ? value1 : value2;
// 不好的寫(xiě)法: 沒(méi)有賦值,應(yīng)當(dāng)使用 if 表達(dá)式
condition ? doSomething() : doSomethingElse();
12.語(yǔ)句
簡(jiǎn)單語(yǔ)句
每一行最多只包含一條語(yǔ)句.所有簡(jiǎn)單的語(yǔ)句都應(yīng)該以分號(hào)(;)結(jié)束.
// 好的寫(xiě)法
const a = 1;
const b = 2;
const c = a + b;
// 不好的寫(xiě)法: 多個(gè)表達(dá)式寫(xiě)在一行
const a = 1;const b = 2;const c = a + b;
返回語(yǔ)句
返回語(yǔ)句當(dāng)返回一個(gè)值的時(shí)候不應(yīng)當(dāng)使用圓括號(hào)包裹,除非在某些情況下這么做可以讓返回值更容易理解.例如:
return;
return collection.size();
return (size > 0 ? size : defaultSize)
復(fù)合語(yǔ)句
復(fù)合語(yǔ)句是大括號(hào)括起來(lái)的語(yǔ)句列表;
- 括起來(lái)的語(yǔ)句應(yīng)當(dāng)較復(fù)合語(yǔ)句多縮進(jìn)一個(gè)層級(jí)
- 開(kāi)始的大括號(hào)應(yīng)當(dāng)在復(fù)合語(yǔ)句所在行的末尾;結(jié)束的大括號(hào)應(yīng)當(dāng)獨(dú)占一行且同復(fù)合語(yǔ)句的開(kāi)始保持同樣的縮進(jìn).
- 當(dāng)括號(hào)時(shí)控制結(jié)構(gòu)的一部分時(shí),諸如if或者for語(yǔ)句,所有語(yǔ)句都需要用打括號(hào)括起來(lái),也包括單個(gè)語(yǔ)句.這個(gè)約定使得我們更方便地添加語(yǔ)句而不用擔(dān)心忘記加括號(hào)而引起bug
- 像if一樣的語(yǔ)句開(kāi)始的關(guān)鍵詞,其后應(yīng)當(dāng)緊跟一個(gè)空格,起始大括號(hào)應(yīng)當(dāng)在空格之后
if語(yǔ)句
if (condition) {
statements
} else if (condition) {
statements
} else {
statements
}
絕不允許在if語(yǔ)句中省略花括號(hào)
// 好的寫(xiě)法
if (condition) {
doSomething();
}
// 不好的寫(xiě)法: 不恰當(dāng)?shù)目崭?if(condition){
doSomething();
}
// 不好的寫(xiě)法: 遺漏花括號(hào)
if (condition)
doSomething();
// 不好的寫(xiě)法: 所有代碼寫(xiě)在一行
if (condition) { doSomething(); }
// 不好的寫(xiě)法: 所有代碼寫(xiě)在一行且沒(méi)有花括號(hào)
if (condition) doSomething();
for語(yǔ)句
for (initialization; condition; update) {
statements
}
for (constiable in object) {
statements
}
當(dāng)使用 for-in 語(yǔ)句時(shí),記得使用 hasOwnProperty() 進(jìn)行雙重檢查來(lái)過(guò)濾出對(duì)象的成員
while語(yǔ)句
while (condition) {
statements
}
do語(yǔ)句
do {
statements
} while (condition)
switch語(yǔ)句
switch (expression) {
case expression:
statements
default:
statements
}
switch下的每一個(gè)case都叮當(dāng)保持一個(gè)縮進(jìn).除第一個(gè)之外包括default在內(nèi)的每一個(gè)case都應(yīng)當(dāng)在之前保持一個(gè)空行
每一組語(yǔ)句(除了default)都應(yīng)當(dāng)以break, return, throw結(jié)尾,或者用一行注釋表示跳過(guò)
// 好的寫(xiě)法
switch (value) {
case 1:
/* falls through */
case 2:
doSomething();
break;
case 3:
return true;
default:
throw new Error('this should not happen');
}
try語(yǔ)句
try {
statements
} catch (constiable) {
statements
} finally {
statements
}
13.嚴(yán)格模式
嚴(yán)格模式應(yīng)當(dāng)僅限在函數(shù)內(nèi)部使用,千萬(wàn)不要在全局使用.
ES6 的模塊自動(dòng)采用嚴(yán)格模式,不管你有沒(méi)有在模塊頭部加上"use strict";。
14.變量聲明
所有的變量在使用前都應(yīng)事先定義.變量定義應(yīng)放在函數(shù)開(kāi)頭.
變量定義前應(yīng)當(dāng)初始化,并且賦值操作符應(yīng)當(dāng)保持一致的縮進(jìn).初始化的變量應(yīng)當(dāng)在未初始化變量之前.
推薦使用ES6的
let和const來(lái)聲明變量
15.函數(shù)聲明
函數(shù)聲明應(yīng)當(dāng)在使用前提前定義.
一個(gè)不是作為方法的函數(shù)(也就是沒(méi)有作為一個(gè)對(duì)象的屬性)應(yīng)當(dāng)使用函數(shù)定義的格式(不是函數(shù)表達(dá)式和Function構(gòu)造器格式).
函數(shù)名和開(kāi)始圓括號(hào)之前不應(yīng)當(dāng)有空格.結(jié)束的圓括號(hào)和右邊的花括號(hào)之間應(yīng)該留一個(gè)空格.右側(cè)的花括號(hào)應(yīng)當(dāng)同function關(guān)鍵字保持同一行.開(kāi)始和結(jié)束括號(hào)之間不應(yīng)該有空格.參數(shù)名之間應(yīng)當(dāng)在逗號(hào)之后保留一個(gè)空格.函數(shù)體應(yīng)當(dāng)保持一級(jí)縮進(jìn)
// 好的寫(xiě)法
function doSomething(arg1, agr2) {
return arg1 + arg2;
}
// 不好的寫(xiě)法: 第一行不恰當(dāng)?shù)目崭?function doSomething (arg1, agr2) {
return arg1 + arg2;
}
// 不好的寫(xiě)法:
const doSomething = function doSomething(arg1, agr2) {
return arg1 + arg2;
}
// 不好的寫(xiě)法: 左側(cè)的花括號(hào)位置不對(duì)
function doSomething(arg1, agr2)
{
return arg1 + arg2;
}
// 錯(cuò)誤的寫(xiě)法: 使用Function構(gòu)造器
const doSomething = new Function('arg1', 'agr2', 'return arg1 + arg2');
16.留白
在邏輯相關(guān)的代碼塊之間添加空行可以提高代碼的可讀性
兩行空行權(quán)限在如下情況使用
- 在不同的源代碼文件之間
- 在類(lèi)和接口定義之間
單行空行權(quán)限在如下情況使用
- 方法之間
- 方法中局部變量和第一行語(yǔ)句之間
- 多行或單行注釋之前
- 方法中邏輯代碼塊之間以提高代碼的可讀性
空格應(yīng)當(dāng)在如下情況中使用
- 關(guān)鍵詞后跟括號(hào)的情況應(yīng)當(dāng)用空格隔開(kāi)
- 參數(shù)列表中逗號(hào)之后應(yīng)當(dāng)保留一個(gè)空格
- 所有的除了點(diǎn)(.)之外的二元運(yùn)算符,其操作數(shù)都應(yīng)當(dāng)用空格隔開(kāi).單目運(yùn)算符的操作數(shù)之間不應(yīng)該用空白隔開(kāi),諸如一元減號(hào),遞增(++),遞減(--)
- for語(yǔ)句中的表達(dá)式之間應(yīng)當(dāng)用空格隔開(kāi)
17. 需要避免的
- 切勿使用像String一類(lèi)的原始包裝類(lèi)型創(chuàng)建的新對(duì)象
- 避免使用eval()
- 避免使用with語(yǔ)句.改語(yǔ)句在嚴(yán)格模式中不復(fù)存在,可能在未來(lái)也將去除
使用工具(eslint)來(lái)強(qiáng)制約束
eslint 規(guī)則
eslint規(guī)則在.eslintrc.js中定義,覺(jué)得不合理的可以禁掉某條規(guī)則,或者有好的建議的也可以添加;
主要注意一下幾條:
- 代碼縮進(jìn)用4空格
- 語(yǔ)句必須默認(rèn)后加分號(hào)
- 使用單引號(hào)
- 提交代碼前將console.log語(yǔ)句刪掉或注釋掉(不然影響其他開(kāi)發(fā)人員調(diào)試)
- 禁止使用const,使用es6的let,const聲明變量
還有一些情況是不需要檢測(cè)的,例如第3方的庫(kù), 框架、組件、ui庫(kù)等等,可以將這些文件放在.eslintignore文件中,可以忽略eslint的檢測(cè)
在文件頂部加上下面這行,可以禁掉整個(gè)文件的eslint規(guī)則
/* eslint-disable */
pre-commit
代碼提交之前會(huì)強(qiáng)制code-review,不符合規(guī)范的不允許提交代碼
使用方法
1.在命令行安裝
npm i --save-dev pre-commit
2.在package.json中配置
{
"scripts": {
"eslint": "eslint ./ --ext js,vue --ignore-pattern .eslintignore --cache --fix",
"lint-message": "echo '開(kāi)始 eslint 檢查, 存在 error 則會(huì)拒絕提交'"
},
"pre-commit": [
"lint-message",
"eslint" // 進(jìn)行eslint檢查并自動(dòng)修復(fù)一些簡(jiǎn)單的格式錯(cuò)誤
],
}
代碼提交之前會(huì)強(qiáng)制code-review,不符合規(guī)范的不允許提交代碼
如果項(xiàng)目實(shí)在沒(méi)時(shí)間去改的話,可以 git commit -m 'XXX' --no-verify 或 git commit -n 'xxx'強(qiáng)制提交
小技巧-vscode可以配置保存自動(dòng)修復(fù)eslint錯(cuò)誤
vscode安裝eslint插件,在配置中配置如下
{
"eslint.autoFixOnSave": true,
"eslint.enable": true,
"eslint.options": {
"extensions": [".js", ".vue", ".jsx"]
},
"eslint.validate": [
{
"language": "vue",
"autoFix": true
},
{
"language": "javascript",
"autoFix": true
},
{
"language": "javascriptreact",
"autoFix": true
}
],
}
配置完成之后,每次保存,都會(huì)自動(dòng)根據(jù)
.eslintrc.js文件自動(dòng)修復(fù)空格,分號(hào)的錯(cuò)誤;但是最好還是在平常的編碼中養(yǎng)成一個(gè)良好的習(xí)慣,而不是依賴(lài)工具.
下列參考給出的文章及書(shū)籍,有時(shí)間一定要好好看一下,會(huì)幫助大家深刻理解JavaScript編碼風(fēng)格的重要性。永遠(yuǎn)記住,規(guī)范能解決大部分問(wèn)題。