ESLint+Prettier代碼規范實踐

前提

本文并不單獨講解 ESLint 和 Prettier 如何配置和運行。

問題

想在團隊中推行一定的代碼規范,并給不符合規范的代碼做檢測和提示。

方案

代碼規范校驗使用 ESLint,但是一開始 ESLint 只有檢測告訴你哪里有問題,常常出現的情況就是一堆 warning,改起來很痛苦。后來 ESLint 提供了 $ ESLint filename --fix 的命令可以自動幫你修復一些不符合規范的代碼。Prettier 是一個代碼格式化工具,可以幫你把代碼格式化成可讀性更好的格式,最典型的就是一行代碼過長的問題。

Lint和Prettier區別

那 ESLint 和 Prettier 的區別是什么呢?eslint(包括其他一些 lint 工具)的主要功能包含代碼格式的校驗,代碼質量的校驗。而 Prettier 只是代碼格式的校驗(并格式化代碼),不會對代碼質量進行校驗。代碼格式問題通常指的是:單行代碼長度、tab長度、空格、逗號表達式等問題。而代碼質量問題指的是:未使用變量、三等號、全局變量聲明等問題。

Lint和Prettier配合使用

為什么要兩者配合使用?因為,第一在 ESLint 推出 --fix 參數前,ESLint 并沒有自動化格式代碼的功能,要對一些格式問題做批量格式化只能用 Prettier 這樣的工具。第二 ESLint 的規則并不能完全包含 Prettier 的規則,兩者不是簡單的誰替代誰的問題。但是在 ESLint 推出 --fix 命令行參數之后,如果你覺得 ESLint 提供的格式化代碼夠用了,也可以不使用 Prettier。

ESLint 和 Prettier 相互合作的時候有一些問題,對于他們交集的部分規則,ESLint 和 Prettier 格式化后的代碼格式不一致。導致的問題是:當你用 Prettier 格式化代碼后再用 ESLint 去檢測,會出現一些因為格式化導致的 warning。這個時候有兩個解決方案:

  1. 運行 Prettier 之后,再使用 eslint --fix 格式化一把,這樣把沖突的部分以 ESLint 的格式為標準覆蓋掉,剩下的 warning 就都是代碼質量問題了。
  2. 在配置 ESLint 的校驗規則時候把和 Prettier 沖突的規則 disable 掉,然后再使用 Prettier 的規則作為校驗規則。那么使用 Prettier 格式化后,使用 ESLint 校驗就不會出現對前者的 warning。

為什么不能先使用 ESLint 再使用 Prettier。針對方案1,如果你后使用 Prettier,那么格式化后提交的代碼在下一次或者別人 checkout 代碼后是通不過 lint 校驗的。針對方案2,其實是可以的,但是本人在實踐中看社區方案的時候有提到某些情況下 eslint --fix 和 prettier 混用會出現格式問題。所以保險起見還是先用 perttier 格式化,再用 eslint 命令校驗,而不用 eslint --fix 命令去格式化。

方案一實踐

  1. 安裝 prettier-eslint(Tip:所有方案前提是你已經安裝 eslint 和 prettier 相關包):

    $ npm install --save-dev prettier-eslint prettier-eslint-cli
    
  2. 運行

    $ npm prettier-eslint "src/**/*.js"
    

    prettier-eslint 會一次執行 prettier 和 eslint --fix 命令。整個流程是:Code ?? prettier ?? eslint --fix ?? Formatted Code。prettier-eslint 的各種參數請參看 https://github.com/prettier/prettier-eslint-cli

方案二實踐

方案二的思路主要是在 eslint 的規則配置文件上做文章,安裝特定的 plugin,把其配置到規則的尾部,實現 prettier 規則對 eslint 規則的覆蓋。

  1. 安裝 plugin:

    $ npm install --save-dev eslint-config-prettier
    
  2. 在 .eslintrc.* 文件里面的 extends 字段添加:

    {
      "extends": [
        ...,
        "已經配置的規則",
    +   "prettier",
    +   "prettier/@typescript-eslint"
      ]
    }
    
    

    我使用的是 TypeScript,所以 plugin 的名字是 prettier/@typescript-eslint。

    如果你想 disable 掉更多的規則可以是如下:

    {
      "extends": [
        ...,
        "已經配置的規則",
        "prettier",
        "prettier/@typescript-eslint",
        "prettier/babel",
        "prettier/flowtype",
        "prettier/react",
        "prettier/standard",
        "prettier/unicorn",
        "prettier/vue"
      ]
    }
    
    

    看名字應該能猜到每個對應的是 disable 哪些規則了吧。

  3. 完成上述兩步可以實現的是運行 eslint 命令會按照 prettier 的規則做相關校驗,但是還是需要分別運行 prettier 和 eslint 命令。社區有一個方案整合了上述兩步,在使用 eslint --fix 時候,實際使用 prettier 來替代 eslint 的格式化功能。
    安裝:

    $ npm install --save-dev eslint-plugin-prettier
    

    修改 .eslintrc.*

    {
      "extends": [
        ...,
        "已經配置的規則",
        "plugin:prettier/recommended"
      ]
    }
    
    

    這個時候你運行 eslint --fix 實際使用的是 Prettier 去格式化文件。eslint-plugin-prettier 具體詳細的配置見:https://github.com/prettier/eslint-plugin-prettier

和VSCode集成使用

上面所有講到的內容都是在你寫完代碼去校驗的,使用的是命令行工具。如果你是一個新手,對規范不是很熟悉,那么碰到的問題就是寫完代碼運行命令行工具后產生海量的 warning。這個時候改起來真的很打擊積極性。如果能夠在寫的代碼的時候讓編輯器提示就能及時改正了。自然我們社區也提供了很多方案,各家的編輯器 Atom、Sublime、VSCode 等主流的編輯器都有相關的插件。我就以 VSCode 為例:

  1. 下載 ESLint Extension


    vscode-eslint-extension.png
  2. 配置 .eslintrc.*

module.exports =  {
  parser:  '@typescript-eslint/parser',
  extends:  [
    'plugin:@typescript-eslint/recommended',
    'prettier/@typescript-eslint',
    'plugin:prettier/recommended'
  ],
  parserOptions:  {
    ecmaVersion:  2018,
    sourceType:  'module'
  },
  // 其他配置
};
  1. 因為我使用了 TypeScript 所以 .eslintrc.* 配置項的值和 javascript 有點不一樣,但是原理是一樣的。如果你沒有使用 TypeScript 那么到上面步驟就結束了。但是 VSCode 的 ESLint 插件沒有天然支持 ts 文件,所以我們還必須自己建立一個設置文件。在項目根目錄下新建 .vscode/settings.json 文件,內容如下:
    {
      "eslint.validate": [
        "javascript",
        "javascriptreact",
        { 
          "language": "typescript",
          "autoFix": true
        },
        { 
          "language": "typescriptreact",
          "autoFix": true
        }
      ]
    }
    

你就可以看到編輯器對代碼有實時提示了。

強制校驗和格式化

講到這里兩個工具配合使用已經講好了,但是這些步驟都依賴于人工自覺,要做到一點點強制功能,我們就可以用到 husky lint-staged 來在 git commit 前強制代碼格式化和代碼校驗。

  1. 安裝

    $npm install --save-dev husky lint-staged
    
  2. 修改 package.json:

    {
      "name": "project-name",
      ...,
      + "husky": {
      +     "hooks": {
      +         "pre-commit": "lint-staged"
      +     }
      + },
      + "lint-staged": {
      +     "src/**/*.{js,jsx,ts,tsx,json,css,scss,md}": [
      +     "prettier --write",
      +     "eslint",
      +     "git add"
      +     ]
      + },
    }
    
  3. 那么在運行 git commit 時候,自動會先去運行 prettier --write 格式化代碼,再運行 eslint 校驗代碼是否符合規范。這兩步都通過后才會提交代碼。如果任何一步失敗,則會停止提交。

如果你使用方案一,lint-staged 配置的命令:

{
  "name": "project-name",
  ...,
  +  "husky": {
  +    "hooks": {
  +      "pre-commit": "lint-staged"
  +    }
  +  },
  + "lint-staged": {
  +   "src/**/*.{js,jsx,ts,tsx,json,css,scss,md}": [
  +     "prettier-eslint",
  +     "git add"
  +   ]
  + },
}

如果你使用了方案二中的 eslint-plugin-prettier,lint-staged 配置的命令:

{
  "name": "project-name",
  ...,
  +  "husky": {
  +    "hooks": {
  +      "pre-commit": "lint-staged"
  +    }
  +  },
  + "lint-staged": {
  +   "src/**/*.{js,jsx,ts,tsx,json,css,scss,md}": [
  +     "eslint --fix",
  +     "git add"
  +   ]
  + },
}

參考文獻

  1. https://eslint.org/
  2. https://prettier.io/
  3. https://restishistory.net/blog/whats-the-difference-between-eslint-and-prettier.html

如果使用的是 TypeScript:

  1. ESLint如何運用到TS項目
  2. 如何和Prettier配合使用
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,936評論 6 535
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,744評論 3 421
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,879評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,181評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,935評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,325評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,384評論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,534評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,084評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,892評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,067評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,623評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,322評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,735評論 0 27
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,990評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,800評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,084評論 2 375

推薦閱讀更多精彩內容