<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          前端團隊代碼規(guī)范最佳實踐!

          共 8617字,需瀏覽 18分鐘

           ·

          2021-12-04 05:22

          點擊上方關(guān)注?前端技術(shù)江湖一起學(xué)習(xí),天天進步


          作者:楊成功

          原文:https://segmentfault.com/a/1190000040948561

          本文從代碼規(guī)范,代碼檢查,代碼格式化,以及編輯器自動化實現(xiàn)的方向,介紹代碼規(guī)范統(tǒng)一在我們團隊的實踐應(yīng)用。

          大綱預(yù)覽

          本文介紹的內(nèi)容包括以下方面:

          • 認識代碼規(guī)范
          • 制定和統(tǒng)一規(guī)范
          • 神技一:ESLint
          • 神技二:Prettier
          • 神技三:VSCode
          • 附錄:命名和項目結(jié)構(gòu)規(guī)范

          認識代碼規(guī)范

          先來思考兩個問題:

          1. 什么是代碼規(guī)范?
          2. 為什么需要代碼規(guī)范?

          如果你是一個經(jīng)驗豐富的前端開發(fā),你一定接觸過這樣的老項目:變量名是?abcfds?這種隨意起的,或者是?name1,?name2?這種帶數(shù)字起名,這樣的變量不加注釋,鬼都不知道它是干什么的。

          這類代碼就是一種典型的不規(guī)范代碼。這樣的代碼除了讓我們開發(fā)人員情緒暴躁,最重要的問題是,它極大的降低了團隊協(xié)作的效率和程序質(zhì)量。

          在團隊協(xié)作過程中,當組內(nèi)其他人需要使用或 review 你的代碼,看到這種情況,除了噴你,還要花費大量時間了解你寫的是什么。同時這樣非常容易造成變量沖突,帶來未知隱患,調(diào)試困難等問題,甚至可以看出一個程序員的編碼態(tài)度和專業(yè)程度。

          當然,代碼規(guī)范包含很多方面,變量命名規(guī)范只是最基礎(chǔ)的規(guī)范。不規(guī)范的地方越多,程序質(zhì)量越低,團隊協(xié)作的效率也就會越低。

          了解了不規(guī)范的代碼以及不規(guī)范代碼帶來的問題,作為前端架構(gòu)師,我們就要思考三個問題:

          1. 如何制定規(guī)范?
          2. 如何統(tǒng)一團隊的規(guī)范?
          3. 如何檢測規(guī)范?

          制定和統(tǒng)一規(guī)范

          像上面給變量隨意亂起名字的情況,在早期的前端項目中非常常見。

          因為早期項目規(guī)模,團隊規(guī)模有限,沒有命名規(guī)范這種意識,隨意起名貌似也沒有太大的問題,只要不重復(fù)就好。但是隨著前端項目規(guī)模越來越大,復(fù)雜度越來越高,不規(guī)范帶來的問題越來越多,這種規(guī)范意識才慢慢的被重視起來。

          經(jīng)過社區(qū)的不斷發(fā)展,協(xié)定了命名包含以下幾種規(guī)范:

          • 下劃線命名:user_name
          • 中劃線命名:user-name
          • 小駝峰命名:userName
          • 大駝峰命名:UserName

          有了這些規(guī)范,開發(fā)者們起名字的時候心里就有譜了。而且這些規(guī)范目前也被大多數(shù)開發(fā)者們接受,如果不按照規(guī)范命名,很可能會被同事吐槽嘍!

          當規(guī)范成為普遍共識之后,大家按照自己的喜好使用不同的規(guī)范,逐漸形成了自己的編碼習(xí)慣。在一個團隊中,每個開發(fā)者往往各自有各自的編碼習(xí)慣。

          然而這又成為了問題。再拿變量舉例:一個團隊中,有的人習(xí)慣用下劃線命名變量,如?user_name;有的人習(xí)慣用駝峰命名變量,如?userName。這兩種命名方式都正確,都符合規(guī)范,但是會造成團隊的代碼風格混亂,無法統(tǒng)一。

          那為什么要統(tǒng)一呢?

          統(tǒng)一的好處有很多。比如我們統(tǒng)一規(guī)定:命名變量用下劃線,命名方法用小駝峰。那么在團隊協(xié)作時,大家看到下劃線就知道這是一個變量,看到小駝峰就知道這是一個方法。十個人的代碼寫出來是一個人的風格,不需要了解其他的編碼風格,實現(xiàn)無障礙協(xié)作。

          十個人的代碼寫出一個人的風格,說起來很理想,但是靠監(jiān)督和自覺實現(xiàn)幾乎是不可能的。

          怎么辦呢?下面就是本文重點:祭出實現(xiàn)代碼規(guī)范的三招神技

          神技一:ESLint

          上面說到,團隊協(xié)作開發(fā)項目,由于每個人的編碼習(xí)慣不同,會寫出各種各樣的代碼。這樣的代碼又亂又難以維護。

          所以我們希望有這樣一個工具,可以制定一套比較完整全面的規(guī)范,如果大家的編碼不符合規(guī)范,程序就會警告甚至報錯,用這種工具來倒逼團隊成員遵守統(tǒng)一的代碼風格。

          這個工具是有的,我們都聽過,就是大名鼎鼎的?ESLint

          ESLint 有兩種能力:

          • 檢查代碼質(zhì)量,如是否有已定義但未使用的變量。
          • 檢查代碼風格,換行,引號,縮進等相關(guān)的規(guī)范。

          這兩種能力幾乎涵蓋了絕大部分代碼規(guī)范,并且具體規(guī)范是可配置的,團隊可以定制自己喜歡的代碼風格。

          定制規(guī)范后,項目運行或熱更新時,ESLint 就會自動檢查代碼是否符合規(guī)范。

          :ESLint 檢查與 TypeScript 檢查有啥區(qū)別?

          TypeScript 只會檢查類型錯誤,而 ESLint 會檢查風格錯誤

          嘗試 ESLint

          首先在項目下安裝:

          $?npm?install?eslint?--save-dev

          然后運行命令初始化配置:eslint --init

          eslint?是一個交互式命令,可以上下切換選擇適合項目的選項;完成會生成?.eslintrc.json?文件。

          基本配置

          .eslintrc.json 的基本配置如下:

          {
          ??"env":?{
          ????"browser":?true,
          ????"es2021":?true,
          ??},
          ??"extends":?[
          ????"eslint:recommended"
          ??],
          ??"parserOptions":?{
          ????"ecmaVersion":?12,
          ????"sourceType":?"module",
          ??},
          ??"rules":?{},
          };

          這個基本配置包含了一套默認推薦的配置,定義在?eslint:recommended?這個擴展中。

          React 配置

          React 在默認配置的基礎(chǔ)上,也有一套推薦的語法配置,定義在?plugin:react/recommended?這個插件中,如果你的前端框架是 React,要定義 eslint 規(guī)范,那么在基本配置上添加下面標記?+?號的配置即可:

          {
          ??"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)在來寫一段代碼,并執(zhí)行規(guī)范檢查。

          新建?index.js?文件,寫入內(nèi)容:

          const?a?=?'13'
          function?add()?{
          ??return?'1'
          }

          從 js 角度講,這兩行代碼是沒問題的。然后我們運行檢查命令:

          $?npx?eslint?index.js

          這時會在控制臺看到報錯:

          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-vars

          2?problems?(2?errors,?0?warnings)

          錯誤的意思是變量?a?和函數(shù)?add?已聲明但未使用,說明代碼不符合約定的規(guī)范。這種異常也很常見,在腳手架構(gòu)建的項目中使用?npm run dev?和?npm start?時就會執(zhí)行上面的檢查命令。

          ESLint 規(guī)范

          上面說過,ESLint 可以自定義檢查規(guī)范,規(guī)范定義在?.eslintrc.json?配置文件的 rules 對象下。

          比如,定義規(guī)范,字符串必須使用雙引號:

          {
          ??"rules":?{
          ????"quotes":?["error",?"double"]
          ??}
          }

          定義好之后,如果你的代碼中字符串使用單引號,ESLint 就會報錯。

          quotes?表示引號規(guī)范,是眾多規(guī)范中的一個,它的值是一個數(shù)組。

          數(shù)組第一項是錯誤級別,是以下 3 個值之一:

          • "off" or 0?- 關(guān)閉規(guī)范
          • "warn" or 1?- 警告級別規(guī)范
          • "error" or 2?- 錯誤級別規(guī)范

          數(shù)組第二項才是真正的規(guī)范,具體完整的規(guī)范參考?這里[1]

          打開上面的網(wǎng)頁,打綠鉤的表示是已配置的。需要自定義直接寫在 rules 里即可。

          神技二:Prettier

          上一步我們用 ESLint 實現(xiàn)了規(guī)范的制定和檢查。當開發(fā)人員完成一段代碼保存時,項目會自動執(zhí)行?eslint?檢查命令檢查代碼,檢查到異常后輸出的控制臺,待開發(fā)人員修復(fù)異常后才能繼續(xù)開發(fā)。

          如果你配置的編碼規(guī)范比較復(fù)雜和嚴格,比如字符串必須單引號,代碼結(jié)尾必須用分號,換行必須是 2 個 tab 且不可以用空格。像這種很細的規(guī)范,大家開發(fā)過程中難免會有不符合,這個時候控制臺就會頻繁報錯,開發(fā)人員就會頻繁修復(fù)一個空格一個標點符號,時間久了異常煩人。

          正因為如此,在腳手架生成的項目中雖然默認都開啟了 ESLint,但是很多人使用不久后覺得煩人,效率低下,所以都手動關(guān)閉了 ESLint。

          那么,有沒有更高效的方法,讓大家非常快捷的寫出完全符合規(guī)范的代碼呢?

          有,它便是第二招神技:Prettier

          Prettier 是當前最流行的代碼格式化工具,它最主要的作用就是格式化代碼。

          什么是格式化?上面我們用 ESLint 定制了編碼規(guī)范,當檢測到不規(guī)范的代碼,提示異常,然后需要我們開發(fā)人員按照提示手動修復(fù)不規(guī)范的地方。

          而格式化的威力,是將不規(guī)范的代碼,按照規(guī)范一鍵自動修復(fù)

          聽起來很振奮人心,我們來試一下。

          首先在項目下安裝:

          $?npm?install?prettier?--save-dev

          然后新建?.prettierrc.json?文件:

          {
          ??"singleQuote":?true,
          ??"semi":?true
          }

          這個配置文件和上面 ESLint 下的 rules 配置作用一致,就是定義代碼規(guī)范 ——— 沒錯,Prettier 也支持定義規(guī)范,然后根據(jù)規(guī)范格式化代碼。

          列一下 Prettier 的常用規(guī)范配置:

          {
          ??"singleQuote":?true,?//?是否單引號
          ??"semi":?false,?//?聲明結(jié)尾使用分號(默認true)
          ??"printWidth":?100,?//?一行的字符數(shù),超過會換行(默認80)
          ??"tabWidth":?2,?//?每個tab相當于多少個空格(默認2)
          ??"useTabs":?true,?//?是否使用tab進行縮進(默認false)
          ??"trailingComma":?"all",?//?多行使用拖尾逗號(默認none)
          ??"bracketSpacing":?true,?//?對象字面量的大括號間使用空格(默認true)
          ??"jsxBracketSameLine":?false,?//?多行JSX中的>放置在最后一行的結(jié)尾,而不是另起一行(默認false)
          ??"arrowParens":?"avoid"?//?只有一個參數(shù)的箭頭函數(shù)的參數(shù)是否帶圓括號(默認avoid)
          }

          定義好配置后,我們在?index.js?文件中寫入內(nèi)容:

          const?a?=?"13"
          function?add()?{
          ??return?"1"
          }

          然后在終端運行格式化命令:

          $?npx?prettier?--write?index.js

          格式化之后,再看 index.js 文件變成了這樣:

          const?a?=?'13';
          function?add()?{
          ??return?'1';
          }

          看到變化了吧,雙引號自動變成了單引號,行結(jié)尾自動加了分號,剛好與配置文件中定義的規(guī)范一致。

          喜大普奔!終于不用再手動修復(fù)不規(guī)范的代碼了,一個命令就能搞定!

          上面是格式化一個文件,當然也支持批量格式化文件。批量格式化通過模糊匹配查找文件,比較常用,建議定義在 script 腳本中,如下:

          //?package.json
          "scripts":?{
          ??"format":?"prettier?--write?\"src/**/*.js\"?\"src/**/*.ts\"",
          }

          Prettier 還支持針對不同后綴的文件設(shè)置不同的代碼規(guī)范,如下:

          {
          ??"semi":?false,
          ??"overrides":?[
          ????{
          ??????"files":?"*.test.js",
          ??????"options":?{
          ????????"semi":?true
          ??????}
          ????},
          ????{
          ??????"files":?["*.json"],
          ??????"options":?{
          ????????"parser":?"json-stringify"
          ??????}
          ????}
          ??]
          }

          :ESLint 與 Prettier 有啥區(qū)別?

          相同點:都可以定義一套代碼規(guī)范。

          不同點:ESLint 會在檢查時對不規(guī)范的代碼提示錯誤;而 Prettier 會直接按照規(guī)范格式化代碼。

          所以,ESLint 和 Prettier 定義的規(guī)范要一致,不能沖突

          神技三:VSCode

          上面,我們通過 ESLint 和 Prettier 兩招神技,實現(xiàn)了代碼規(guī)范制定,代碼規(guī)范檢查,以及根據(jù)規(guī)范一個命令格式化代碼,使得統(tǒng)一團隊代碼風格變的非常容易。

          然而,突破效率的挑戰(zhàn)是沒有極限的。這時候又有小伙伴發(fā)聲了:雖然是容易了,但是檢查代碼還是得依賴檢查命令,格式化代碼也得依賴格式化命令,這樣總顯得不夠優(yōu)雅。

          好吧,不夠優(yōu)雅,那還有優(yōu)雅的解決方案嗎?

          答案是有。它就是我們的第三招神技 —— VSCode

          強大的插件

          VSCode 對我們前端來說都不陌生,是我們?nèi)杖障喟榈拈_發(fā)武器。當前 VSCode 幾乎統(tǒng)一了前端圈的編輯器,功能強大,倍受好評。

          既然能得到如此廣泛的認可,那么就必然有它的優(yōu)越性。VSCode 除了輕量啟動速度快,最強大的是其豐富多樣的插件,能滿足不用使用者各種各樣的需求。

          在眾多插件中,ESLint?就是非常強大的一個。沒錯,這個插件就是我們前面說到的神技第一招 ESLint 在 VSCode 上支持的同名插件。截圖如下:

          28aefafbe33afc27342d426fffdaa5e5.webpimage.png

          安裝了這個插件之后,之前需要在終端執(zhí)行 eslint 命令才能檢查出來的異常,現(xiàn)在直接標記在你的代碼上了!

          即使是你敲錯了一個符號,該插件也會實時的追蹤到你錯誤的地方,然后給出標記和異常提醒。這簡直大大提升了開發(fā)效率,再也不用執(zhí)行命令來檢查代碼了,看誰還說不優(yōu)雅。

          既然編輯器有 ESLint 插件,那是不是也有 Prettier 插件呢?猜對了,當然有插件,插件全名叫?Prettier - Code formatter,截圖如下,在 VSCode 中搜索安裝即可。

          3cf1da1c91856c5f80ca6906ba9f1126.webpimage.png

          Prettier 插件安裝之后會作為編輯器的一個格式化程序。在代碼中右鍵格式化,就可以選擇 Prettier 來格式化當前代碼。

          如果要想 Prettier 實現(xiàn)自動化,則還需要在編輯器中配置。

          編輯器配置

          VSCode 中有一個用戶設(shè)置?setting.json?文件,其中保存了用戶對編輯器的自定義配置。

          這個配置非常豐富,詳見官網(wǎng)[2]。首先我們在這個配置當中將 Prettier 設(shè)置為默認格式化程序:

          {
          ??"editor.defaultFormatter":?"esbenp.prettier-vscode",
          ??"[javascript]":?{
          ????"editor.defaultFormatter":?"esbenp.prettier-vscode"
          ??}
          }

          設(shè)置好這一步之后,重點來了!?我們再來配置保存文件自動格式化:

          {
          ??"editor.formatOnSave":?true
          }

          配好之后,神奇的事情發(fā)生了:當你寫完代碼保存的時候,發(fā)現(xiàn)你正在編輯的文件立刻被格式化了。也就是說,無論你的代碼按不按照規(guī)范寫,保存的時候自動幫你格式化成規(guī)范的代碼。

          這一步其實是保存文件的時候自動執(zhí)行了格式化命令。因為我們上面配置了默認格式化程序為 Prettier,現(xiàn)在又配了保存時格式化,相當于將文件保存和?prettier?命令連接了起來。

          到這一步,在三大神技的加持之下,我們已經(jīng)實現(xiàn)了代碼的自動檢查與自動格式化,現(xiàn)在你編碼的時候不需要考慮什么格式規(guī)范的問題,只要正常保存,編輯器會自動幫你做好這些事情。

          共享編輯器配置

          上面我們在編輯器經(jīng)過一頓配置,終于實現(xiàn)了自動格式化。現(xiàn)在我們要把這些設(shè)置同步給團隊內(nèi)的其他成員,該怎么辦,難道要一個一個再配一遍?

          別慌,不用這么麻煩。VSCode 的設(shè)置分為兩類:

          • 用戶設(shè)置:應(yīng)用于整個編輯器
          • 工作區(qū)設(shè)置:應(yīng)用于當前目錄/工作區(qū)

          這兩類的配置內(nèi)容是一模一樣的,區(qū)別只是優(yōu)先級的問題。如果你打開的項目目錄包含工作區(qū)設(shè)置,那么這個工作區(qū)設(shè)置會覆蓋掉當前的用戶設(shè)置。

          所以要想將設(shè)置同步給團隊內(nèi)的其他成員,我們不需要去改動用戶設(shè)置,只需要在項目目錄下新建一個工作區(qū)設(shè)置即可。

          添加工作區(qū)設(shè)置方法:在項目根目錄下新建?.vscode/setting.json?文件,在這里寫需要統(tǒng)一的編輯器配置。所以我們把上面的 Prettier 配置寫在這里即可實現(xiàn)共享。

          附錄:命名和項目結(jié)構(gòu)規(guī)范

          上面介紹了代碼規(guī)范,代碼檢查和代碼格式化,統(tǒng)一代碼風格已經(jīng)很全面了。

          在團隊開發(fā)過程當中,我們也積累了一些并不會寫在配置文件里的規(guī)范,這些規(guī)范在一個團隊當中也是非常重要。這部分算是我們的團隊規(guī)范的分享吧。

          主要說兩部分:命名規(guī)范和項目結(jié)構(gòu)規(guī)范。

          命名規(guī)范

          命名規(guī)范,文章開頭也說了,變量的四種命名規(guī)范。但是什么地方用哪種規(guī)范,我們也是有約定的。

          • 變量命名:下劃線?user_id
          • CSS-Class 命名:中劃線?user-id
          • 方法函數(shù)命名:小駝峰?userId
          • JS-Class 命名:大駝峰?UserId
          • 文件夾命名:中劃線?user-id
          • 文件夾下組件命名:中劃線?user-id
          • 組件導(dǎo)出命名:大駝峰?UserId

          項目結(jié)構(gòu)規(guī)范

          項目結(jié)構(gòu)規(guī)范主要是指?src?文件夾下的結(jié)構(gòu)組織。

          |--?src
          ????|--?index.tsx?#?入口文件
          ????|--?assets?#?靜態(tài)資源目錄
          ????|--?components?#?公共組件目錄
          ????|???|--?header
          ????|???|???|--?index.tsx
          ????|???|???|--?index.less
          ????|--?stores?#?狀態(tài)管理目錄,與?pages?結(jié)構(gòu)對應(yīng)
          ????|???|--?admins
          ????|???|???|--?index.tsx?#?狀態(tài)文件
          ????|???|???|--?types.ts??#?定義狀態(tài)類型
          ????|???|--?index.tsx
          ????|--?pages?#?頁面目錄,與?stores?結(jié)構(gòu)對應(yīng)
          ????|???|--?admins
          ????|???|???|--?index.tsx
          ????|???|???|--?index.less
          ????|--?request
          ????|???|--?index.ts?#?axios?實例,全局請求處理
          ????|--?router
          ????|???|--?home.tsx
          ????|???|--?index.tsx
          ????|???|--?root.tsx
          ????|--?styles?#?全局樣式
          ????|???|--?common.less
          ????|???|--?index.less
          ????|--?utils?#?工具目錄
          ????????|--?index.ts

          參考資料

          [1]

          https://eslint.bootcss.com/docs/rules/:?https://link.juejin.cn?target=https%3A%2F%2Feslint.bootcss.com%2Fdocs%2Frules%2F

          [2]

          https://code.visualstudio.com/docs/getstarted/settings:?https://link.juejin.cn?target=https%3A%2F%2Fcode.visualstudio.com%2Fdocs%2Fgetstarted%2Fsettings

          The End

          歡迎自薦投稿到《前端技術(shù)江湖》,如果你覺得這篇內(nèi)容對你挺有啟發(fā),記得點個?「在看」


          點個『在看』支持下?e9c336956e5f712b0f617f9382accb36.webp

          瀏覽 80
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  少妇探花| 一级a爱视频 | 做爱网站免费观看 | 国产伦子伦一级A片在线 | 欧美激情一区二区三区p站 |