前端架构师神技,三招统一团队代码风格
本文從代碼規(guī)范,代碼檢查,代碼格式化,以及編輯器自動(dòng)化實(shí)現(xiàn)的方向,介紹代碼規(guī)范統(tǒng)一在我們團(tuán)隊(duì)的實(shí)踐應(yīng)用。
大綱預(yù)覽
本文介紹的內(nèi)容包括以下方面:
- 認(rèn)識(shí)代碼規(guī)范
- 制定和統(tǒng)一規(guī)范
- 神技一:ESLint
- 神技二:Prettier
- 神技三:VSCode
- 附錄:命名和項(xiàng)目結(jié)構(gòu)規(guī)范
認(rèn)識(shí)代碼規(guī)范
先來(lái)思考兩個(gè)問(wèn)題:
1.什么是代碼規(guī)范?
2.為什么需要代碼規(guī)范?
如果你是一個(gè)經(jīng)驗(yàn)豐富的前端開(kāi)發(fā),你一定接觸過(guò)這樣的老項(xiàng)目:變量名是abc,fds這種隨意起的,或者是name1,name2這種帶數(shù)字起名,這樣的變量不加注釋,鬼都不知道他是干什么的。
這類(lèi)代碼就是一種典型的不規(guī)范代碼,這樣的代碼除了讓我們開(kāi)發(fā)人員情緒暴躁,最重要的問(wèn)題是,它極大的降低了團(tuán)隊(duì)協(xié)作的效率和程序質(zhì)量。
在團(tuán)隊(duì)協(xié)作過(guò)程中,當(dāng)組內(nèi)其他人需要使用或review你的代碼,看到這種情況,除了噴你,還要花費(fèi)大量時(shí)間了解你寫(xiě)的是什么。同樣這樣非常容易造成變量沖突,帶來(lái)位置隱患,調(diào)試?yán)щy等問(wèn)題,甚至可以看出一個(gè)程序員的編碼態(tài)度和專(zhuān)業(yè)程度。
當(dāng)然,代碼規(guī)范包含很多方面,變量命名規(guī)范只是最基礎(chǔ)的規(guī)范。不規(guī)范的地方越多,程序質(zhì)量越低,團(tuán)隊(duì)協(xié)作的效率也會(huì)越低。
了解了不規(guī)范的代碼以及不規(guī)范代碼帶來(lái)的問(wèn)題,作為前端架構(gòu)師,我們要思考三個(gè)問(wèn)題:
1.如何制定規(guī)范?
2.如何統(tǒng)一團(tuán)隊(duì)的規(guī)范?
3.如何檢測(cè)規(guī)范?
制定和統(tǒng)一規(guī)范
像上面給變量隨意亂起名字的情況,在早期的前端項(xiàng)目中非常常見(jiàn)。
因?yàn)樵缙陧?xiàng)目規(guī)模,團(tuán)隊(duì)規(guī)模有限,沒(méi)有命名規(guī)范這種意識(shí),隨意起名貌似也沒(méi)有太大的問(wèn)題,只要不重復(fù)就好。但是隨著前端項(xiàng)目規(guī)模越來(lái)越大,復(fù)雜度越來(lái)越高,不規(guī)范帶來(lái)的問(wèn)題越來(lái)越多,這種規(guī)范意識(shí)才慢慢的被重視起來(lái)。
經(jīng)過(guò)社區(qū)的不斷發(fā)展,協(xié)定了命名包含以下幾種規(guī)范:
- 下劃線(xiàn)命名:user_name
- 中劃線(xiàn)命名:user-name
- 小駝峰命名:userName
- 大駝峰命名:UserName
有了這些規(guī)范,開(kāi)發(fā)者起名字的時(shí)候心里就有譜了。而且這些規(guī)范目前也被大多數(shù)開(kāi)發(fā)者接受,如果不按照規(guī)范命名,很可能會(huì)被同事吐槽嘍!
當(dāng)規(guī)范成為普遍共識(shí)之后,大家按照自己的喜好使用不同的規(guī)范,逐漸形成了自己的編碼習(xí)慣。在一個(gè)團(tuán)隊(duì)中,每個(gè)開(kāi)發(fā)者往往按照各自有各自的編碼習(xí)慣。
然而這又成了問(wèn)題。再拿變量舉例,一個(gè)團(tuán)隊(duì)中,有的人習(xí)慣用下劃線(xiàn)命名變量,如user_name;有的人習(xí)慣用駝峰命名變量,如userName。這兩種命名方式都正確,都符合規(guī)范,但是會(huì)造成團(tuán)隊(duì)的代碼風(fēng)格混亂,無(wú)法統(tǒng)一。
那為什么要統(tǒng)一呢?
統(tǒng)一的好處有很多。比如我們統(tǒng)一規(guī)定:命名變量用下劃線(xiàn),命名方法用小駝峰。那么在團(tuán)隊(duì)協(xié)作時(shí),大家看到下劃線(xiàn)就知道這是一個(gè)變量,看到小駝峰就知道這是一個(gè)方法。十個(gè)人的代碼寫(xiě)出來(lái)是一個(gè)人的風(fēng)格,不需要了解其他的編碼風(fēng)格,實(shí)現(xiàn)無(wú)障礙協(xié)作。
十個(gè)人的代碼寫(xiě)出一個(gè)人的風(fēng)格,說(shuō)起來(lái)很理想,但是考監(jiān)督和自覺(jué)實(shí)現(xiàn)幾乎不可能。
怎么辦呢?下面就是本文重點(diǎn):祭出實(shí)現(xiàn)代碼規(guī)范的三招神技。
神技一:ESLint
上面說(shuō)到,團(tuán)隊(duì)協(xié)作開(kāi)發(fā)項(xiàng)目,由于每個(gè)人的編碼習(xí)慣不同,會(huì)寫(xiě)出各種各樣的代碼。這樣的代碼又亂又難以維護(hù)。
所以我們希望有這樣的一個(gè)工具,可以指定一套比較完整全面的規(guī)范。如果大家的編碼不符合規(guī)范,程序就會(huì)警告甚至報(bào)錯(cuò),用這種工具來(lái)倒逼團(tuán)隊(duì)成員遵守統(tǒng)一的代碼風(fēng)格。
這個(gè)工具是有的,我們都聽(tīng)過(guò),就是大名鼎鼎的 ESLint。
ESLint有兩種能力:
- 檢查代碼質(zhì)量,如是否有已定義但未使用的變量。
- 檢查代碼風(fēng)格,換行,引號(hào),縮進(jìn)等相關(guān)的規(guī)范。
這兩種能力幾乎涵蓋了絕大部分代碼規(guī)范,并且具體規(guī)范是可配置的,團(tuán)隊(duì)可以定制自己喜歡的代碼風(fēng)格。
定制規(guī)范后,項(xiàng)目運(yùn)行或熱更新后,ESLint就會(huì)自動(dòng)檢查代碼是否符合規(guī)范。
問(wèn):ESLint檢查與TypeScript檢查有啥區(qū)別?
TypeScript只會(huì)檢查類(lèi)型錯(cuò)誤,而ESLint]會(huì)檢查風(fēng)格錯(cuò)誤。
嘗試ESLint
首先在項(xiàng)目下安裝:
然后運(yùn)行命令初始化配置:eslint --init
eslint是一個(gè)交互式命令,可以上下切換選擇適合項(xiàng)目的選項(xiàng);完全會(huì)生成 【然后運(yùn)行命令初始化配置:eslint --init
eslint 是一個(gè)交互式命令,可以上下切換選擇適合項(xiàng)目的選項(xiàng);完成會(huì)生成 【.eslintrc.json 】文件。
基本配置
.eslintrc.json的基本配置如下:
這個(gè)基本配置包含了一套默認(rèn)推薦的配置,定義在eslint:recommended 這個(gè)擴(kuò)展中。
React配置
React在默認(rèn)配置的基礎(chǔ)上,也有一套推薦的語(yǔ)法配置,定義在plugin:react/recommended 這個(gè)插件中,如果你的前端框架是 React,要定義 eslint 規(guī)范,那么在基本配置上添加下面標(biāo)記 + 號(hào)的配置即可:
{"env": {"browser": true,"es2021": true},"extends": ["eslint:recommended", + "plugin:react/recommended"],"parserOptions": { + "ecmaFeatures": { + "jsx": true + },"ecmaVersion": 12,"sourceType": "module"}, + "plugins": [ + "react" + ],"rules": {} };React + TS 配置
若要 React 支持 TS,還要加一些額外配置:
{"env": {"browser": true,"es2021": true},"extends": ["eslint:recommended","plugin:react/recommended" + "plugin:@typescript-eslint/recommended"], + "parser": "@typescript-eslint/parser","parserOptions": {"ecmaFeatures": {"jsx": true},"ecmaVersion": 12,"sourceType": "module"},"plugins": ["react", + "@typescript-eslint"],"rules": {} };代碼檢查
上面定義好規(guī)范之后,我們現(xiàn)在來(lái)寫(xiě)一段代碼,并執(zhí)行規(guī)范檢查。
新建 index.js 文件,寫(xiě)入內(nèi)容:
const a = '13' function add() {return '1' }從 js 角度講,這兩行代碼是沒(méi)問(wèn)題的。然后我們運(yùn)行檢查命令:
npx eslint index.js這時(shí)會(huì)在控制臺(tái)看到報(bào)錯(cuò):
2:7 error 'a' is assigned a value but never used no-unused-vars 4:10 error 'add' is defined but never used no-unused-vars2 problems (2 errors, 0 warnings)錯(cuò)誤的意思是變量 a 和函數(shù) add 已聲明但未使用,說(shuō)明代碼不符合約定的規(guī)范。這種異常也很常見(jiàn),在腳手架構(gòu)建的項(xiàng)目中使用 npm run dev 和 npm start 時(shí)就會(huì)執(zhí)行上面的檢查命令。
ESLint 規(guī)范
上面說(shuō)過(guò),ESLint 可以自定義檢查規(guī)范,規(guī)范定義在 .eslintrc.json 配置文件的 rules 對(duì)象下。
比如,定義規(guī)范,字符串必須使用雙引號(hào):
{"rules": {"quotes": ["error", "double"]} }定義好之后,如果你的代碼中字符串使用單引號(hào),ESLint 就會(huì)報(bào)錯(cuò)。
quotes 表示引號(hào)規(guī)范,是眾多規(guī)范中的一個(gè),它的值是一個(gè)數(shù)組。
數(shù)組第一項(xiàng)是錯(cuò)誤級(jí)別,是以下 3 個(gè)值之一:
"off" or 0 - 關(guān)閉規(guī)范
"warn" or 1 - 警告級(jí)別規(guī)范
"error" or 2 - 錯(cuò)誤級(jí)別規(guī)范
數(shù)組第二項(xiàng)才是真正的規(guī)范,具體完整的規(guī)范參考 這里
打開(kāi)上面的網(wǎng)頁(yè),打綠鉤的表示是已配置的。需要自定義直接寫(xiě)在 rules 里即可。
神技二:Prettier
上一步我們用 ESLint 實(shí)現(xiàn)了規(guī)范的制定和檢查。當(dāng)開(kāi)發(fā)人員完成一段代碼保存時(shí),項(xiàng)目會(huì)自動(dòng)執(zhí)行 eslint 檢查命令檢查代碼,檢查到異常后輸出的控制臺(tái),待開(kāi)發(fā)人員修復(fù)異常后才能繼續(xù)開(kāi)發(fā)。
如果你配置的編碼規(guī)范比較復(fù)雜和嚴(yán)格,比如字符串必須單引號(hào),代碼結(jié)尾必須用分號(hào),換行必須是 2 個(gè) tab 且不可以用空格。像這種很細(xì)的規(guī)范,大家開(kāi)發(fā)過(guò)程中難免會(huì)有不符合,這個(gè)時(shí)候控制臺(tái)就會(huì)頻繁報(bào)錯(cuò),開(kāi)發(fā)人員就會(huì)頻繁修復(fù)一個(gè)空格一個(gè)標(biāo)點(diǎn)符號(hào),時(shí)間久了異常煩人。
正因?yàn)槿绱?#xff0c;在腳手架生成的項(xiàng)目中雖然默認(rèn)都開(kāi)啟了 ESLint,但是很多人使用不久后覺(jué)得煩人,效率低下,所以都手動(dòng)關(guān)閉了 ESLint。
那么,有沒(méi)有更高效的方法,讓大家非常快捷的寫(xiě)出完全符合規(guī)范的代碼呢?
有,它便是第二招神技:Prettier
Prettier 是當(dāng)前最流行的代碼格式化工具,它最主要的作用就是格式化代碼。
什么是格式化?上面我們用 ESLint 定制了編碼規(guī)范,當(dāng)檢測(cè)到不規(guī)范的代碼,提示異常,然后需要我們開(kāi)發(fā)人員按照提示手動(dòng)修復(fù)不規(guī)范的地方。
而格式化的威力,是將不規(guī)范的代碼,按照規(guī)范一鍵自動(dòng)修復(fù)。
聽(tīng)起來(lái)很振奮人心,我們來(lái)試一下。
首先在項(xiàng)目下安裝:
npm install prettier --save-dev然后新建 【.prettierrc.json】 文件:
{"singleQuote": true,"semi": true }這個(gè)配置文件和上面 ESLint 下的 rules 配置作用一致,就是定義代碼規(guī)范 ——— 沒(méi)錯(cuò),Prettier 也支持定義規(guī)范,然后根據(jù)規(guī)范格式化代碼。
列一下 Prettier 的常用規(guī)范配置:
{"singleQuote": true, // 是否單引號(hào)"semi": false, // 聲明結(jié)尾使用分號(hào)(默認(rèn)true)"printWidth": 100, // 一行的字符數(shù),超過(guò)會(huì)換行(默認(rèn)80)"tabWidth": 2, // 每個(gè)tab相當(dāng)于多少個(gè)空格(默認(rèn)2)"useTabs": true, // 是否使用tab進(jìn)行縮進(jìn)(默認(rèn)false)"trailingComma": "all", // 多行使用拖尾逗號(hào)(默認(rèn)none)"bracketSpacing": true, // 對(duì)象字面量的大括號(hào)間使用空格(默認(rèn)true)"jsxBracketSameLine": false, // 多行JSX中的>放置在最后一行的結(jié)尾,而不是另起一行(默認(rèn)false)"arrowParens": "avoid" // 只有一個(gè)參數(shù)的箭頭函數(shù)的參數(shù)是否帶圓括號(hào)(默認(rèn)avoid) }定義好配置后,我們?cè)?index.js 文件中寫(xiě)入內(nèi)容:
const a = "13" function add() {return "1" }然后在終端運(yùn)行格式化命令:
npx prettier --write index.js格式化之后,再看 index.js 文件變成了這樣:
const a = '13'; function add() {return '1'; }看到變化了吧,雙引號(hào)自動(dòng)變成了單引號(hào),行結(jié)尾自動(dòng)加了分號(hào),剛好與配置文件中定義的規(guī)范一致。
喜大普奔!終于不用再手動(dòng)修復(fù)不規(guī)范的代碼了,一個(gè)命令就能搞定!
上面是格式化一個(gè)文件,當(dāng)然也支持批量格式化文件。批量格式化通過(guò)模糊匹配查找文件,比較常用,建議定義在 script 腳本中,如下:
// package.json "scripts": {"format": "prettier --write \"src/**/*.js\" \"src/**/*.ts\"", }Prettier 還支持針對(duì)不同后綴的文件設(shè)置不同的代碼規(guī)范,如下:
{"semi": false,"overrides": [{"files": "*.test.js","options": {"semi": true}},{"files": ["*.json"],"options": {"parser": "json-stringify"}}] }問(wèn):ESLint 與 Prettier 有啥區(qū)別?
相同點(diǎn):都可以定義一套代碼規(guī)范。
不同點(diǎn):ESLint 會(huì)在檢查時(shí)對(duì)不規(guī)范的代碼提示錯(cuò)誤;而 Prettier 會(huì)直接按照規(guī)范格式化代碼。
所以,ESLint 和 Prettier 定義的規(guī)范要一致,不能沖突。
神技三:VSCode
上面,我們通過(guò) ESLint 和 Prettier 兩招神技,實(shí)現(xiàn)了代碼規(guī)范制定,代碼規(guī)范檢查,以及根據(jù)規(guī)范一個(gè)命令格式化代碼,使得統(tǒng)一團(tuán)隊(duì)代碼風(fēng)格變的非常容易。
然而,突破效率的挑戰(zhàn)是沒(méi)有極限的。這時(shí)候又有小伙伴發(fā)聲了:雖然是容易了,但是檢查代碼還是得依賴(lài)檢查命令,格式化代碼也得依賴(lài)格式化命令,這樣總顯得不夠優(yōu)雅。
好吧,不夠優(yōu)雅,那還有優(yōu)雅的解決方案嗎?
答案是有。它就是我們的第三招神技 —— VSCode
強(qiáng)大的插件
VSCode 對(duì)我們前端來(lái)說(shuō)都不陌生,是我們?nèi)杖障喟榈拈_(kāi)發(fā)武器。當(dāng)前 VSCode 幾乎統(tǒng)一了前端圈的編輯器,功能強(qiáng)大,倍受好評(píng)。
既然能得到如此廣泛的認(rèn)可,那么就必然有它的優(yōu)越性。VSCode 除了輕量啟動(dòng)速度快,最強(qiáng)大的是其豐富多樣的插件,能滿(mǎn)足不用使用者各種各樣的需求。
在眾多插件中,ESLint 就是非常強(qiáng)大的一個(gè)。沒(méi)錯(cuò),這個(gè)插件就是我們前面說(shuō)到的神技第一招 ESLint 在 VSCode 上支持的同名插件。截圖如下:
安裝了這個(gè)插件之后,之前需要在終端執(zhí)行 eslint 命令才能檢查出來(lái)的異常,現(xiàn)在直接標(biāo)記在你的代碼上了!
即使是你敲錯(cuò)了一個(gè)符號(hào),該插件也會(huì)實(shí)時(shí)的追蹤到你錯(cuò)誤的地方,然后給出標(biāo)記和異常提醒。這簡(jiǎn)直大大提升了開(kāi)發(fā)效率,再也不用執(zhí)行命令來(lái)檢查代碼了,看誰(shuí)還說(shuō)不優(yōu)雅。
既然編輯器有 ESLint 插件,那是不是也有 Prettier 插件呢?猜對(duì)了,當(dāng)然有插件,插件全名叫 Prettier - Code formatter,截圖如下,在 VSCode 中搜索安裝即可。
rettier 插件安裝之后會(huì)作為編輯器的一個(gè)格式化程序。在代碼中右鍵格式化,就可以選擇 Prettier 來(lái)格式化當(dāng)前代碼。
如果要想 Prettier 實(shí)現(xiàn)自動(dòng)化,則還需要在編輯器中配置。
編輯器配置
VSCode 中有一個(gè)用戶(hù)設(shè)置 setting.json 文件,其中保存了用戶(hù)對(duì)編輯器的自定義配置。
這個(gè)配置非常豐富,詳見(jiàn)官網(wǎng)。首先我們?cè)谶@個(gè)配置當(dāng)中將 Prettier 設(shè)置為默認(rèn)格式化程序:
{"editor.defaultFormatter": "esbenp.prettier-vscode","[javascript]": {"editor.defaultFormatter": "esbenp.prettier-vscode"} }設(shè)置好這一步之后,重點(diǎn)來(lái)了! 我們?cè)賮?lái)配置保存文件自動(dòng)格式化:
{"editor.formatOnSave": true }配好之后,神奇的事情發(fā)生了:當(dāng)你寫(xiě)完代碼保存的時(shí)候,發(fā)現(xiàn)你正在編輯的文件立刻被格式化了。也就是說(shuō),無(wú)論你的代碼按不按照規(guī)范寫(xiě),保存的時(shí)候自動(dòng)幫你格式化成規(guī)范的代碼。
這一步其實(shí)是保存文件的時(shí)候自動(dòng)執(zhí)行了格式化命令。因?yàn)槲覀兩厦媾渲昧四J(rèn)格式化程序?yàn)?Prettier,現(xiàn)在又配了保存時(shí)格式化,相當(dāng)于將文件保存和 prettier 命令連接了起來(lái)。
到這一步,在三大神技的加持之下,我們已經(jīng)實(shí)現(xiàn)了代碼的自動(dòng)檢查與自動(dòng)格式化,現(xiàn)在你編碼的時(shí)候不需要考慮什么格式規(guī)范的問(wèn)題,只要正常保存,編輯器會(huì)自動(dòng)幫你做好這些事情。
共享編輯器配置
上面我們?cè)诰庉嬈鹘?jīng)過(guò)一頓配置,終于實(shí)現(xiàn)了自動(dòng)格式化。現(xiàn)在我們要把這些設(shè)置同步給團(tuán)隊(duì)內(nèi)的其他成員,該怎么辦,難道要一個(gè)一個(gè)再配一遍?
別慌,不用這么麻煩。VSCode 的設(shè)置分為兩類(lèi):
用戶(hù)設(shè)置:應(yīng)用于整個(gè)編輯器
工作區(qū)設(shè)置:應(yīng)用于當(dāng)前目錄/工作區(qū)
這兩類(lèi)的配置內(nèi)容是一模一樣的,區(qū)別只是優(yōu)先級(jí)的問(wèn)題。如果你打開(kāi)的項(xiàng)目目錄包含工作區(qū)設(shè)置,那么這個(gè)工作區(qū)設(shè)置會(huì)覆蓋掉當(dāng)前的用戶(hù)設(shè)置。
所以要想將設(shè)置同步給團(tuán)隊(duì)內(nèi)的其他成員,我們不需要去改動(dòng)用戶(hù)設(shè)置,只需要在項(xiàng)目目錄下新建一個(gè)工作區(qū)設(shè)置即可。
添加工作區(qū)設(shè)置方法:在項(xiàng)目根目錄下新建 .vscode/setting.json 文件,在這里寫(xiě)需要統(tǒng)一的編輯器配置。所以我們把上面的 Prettier 配置寫(xiě)在這里即可實(shí)現(xiàn)共享。
附錄:命名和項(xiàng)目結(jié)構(gòu)規(guī)范
上面介紹了代碼規(guī)范,代碼檢查和代碼格式化,統(tǒng)一代碼風(fēng)格已經(jīng)很全面了。
在團(tuán)隊(duì)開(kāi)發(fā)過(guò)程當(dāng)中,我們也積累了一些并不會(huì)寫(xiě)在配置文件里的規(guī)范,這些規(guī)范在一個(gè)團(tuán)隊(duì)當(dāng)中也是非常重要。這部分算是我們的團(tuán)隊(duì)規(guī)范的分享吧。
主要說(shuō)兩部分:命名規(guī)范和項(xiàng)目結(jié)構(gòu)規(guī)范。
命名規(guī)范
命名規(guī)范,文章開(kāi)頭也說(shuō)了,變量的四種命名規(guī)范。但是什么地方用哪種規(guī)范,我們也是有約定的。
變量命名:下劃線(xiàn) user_id
CSS-Class 命名:中劃線(xiàn) user-id
方法函數(shù)命名:小駝峰 userId
JS-Class 命名:大駝峰 UserId
文件夾命名:中劃線(xiàn) user-id
文件夾下組件命名:中劃線(xiàn) user-id
組件導(dǎo)出命名:大駝峰 UserId
項(xiàng)目結(jié)構(gòu)規(guī)范
項(xiàng)目結(jié)構(gòu)規(guī)范主要是指 src 文件夾下的結(jié)構(gòu)組織。
總結(jié)
以上是生活随笔為你收集整理的前端架构师神技,三招统一团队代码风格的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【转载】听说树莓派性能差,什么最好别尝试
- 下一篇: 本地生成RDL报表文件的创建工具