ESLint+Prettier代碼規(guī)范實(shí)踐

前提

本文并不單獨(dú)講解 ESLint 和 Prettier 如何配置和運(yùn)行悴侵。

問題

想在團(tuán)隊(duì)中推行一定的代碼規(guī)范,并給不符合規(guī)范的代碼做檢測和提示肖揣。

方案

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

Lint和Prettier區(qū)別

那 ESLint 和 Prettier 的區(qū)別是什么呢宰衙?eslint(包括其他一些 lint 工具)的主要功能包含代碼格式的校驗(yàn)平道,代碼質(zhì)量的校驗(yàn)。而 Prettier 只是代碼格式的校驗(yàn)(并格式化代碼)菩浙,不會對代碼質(zhì)量進(jìn)行校驗(yàn)巢掺。代碼格式問題通常指的是:單行代碼長度句伶、tab長度劲蜻、空格、逗號表達(dá)式等問題考余。而代碼質(zhì)量問題指的是:未使用變量先嬉、三等號、全局變量聲明等問題楚堤。

Lint和Prettier配合使用

為什么要兩者配合使用疫蔓?因?yàn)椋谝辉?ESLint 推出 --fix 參數(shù)前身冬,ESLint 并沒有自動化格式代碼的功能衅胀,要對一些格式問題做批量格式化只能用 Prettier 這樣的工具。第二 ESLint 的規(guī)則并不能完全包含 Prettier 的規(guī)則酥筝,兩者不是簡單的誰替代誰的問題滚躯。但是在 ESLint 推出 --fix 命令行參數(shù)之后,如果你覺得 ESLint 提供的格式化代碼夠用了,也可以不使用 Prettier掸掏。

ESLint 和 Prettier 相互合作的時候有一些問題茁影,對于他們交集的部分規(guī)則,ESLint 和 Prettier 格式化后的代碼格式不一致丧凤。導(dǎo)致的問題是:當(dāng)你用 Prettier 格式化代碼后再用 ESLint 去檢測募闲,會出現(xiàn)一些因?yàn)楦袷交瘜?dǎo)致的 warning。這個時候有兩個解決方案:

  1. 運(yùn)行 Prettier 之后愿待,再使用 eslint --fix 格式化一把浩螺,這樣把沖突的部分以 ESLint 的格式為標(biāo)準(zhǔn)覆蓋掉,剩下的 warning 就都是代碼質(zhì)量問題了仍侥。
  2. 在配置 ESLint 的校驗(yàn)規(guī)則時候把和 Prettier 沖突的規(guī)則 disable 掉年扩,然后再使用 Prettier 的規(guī)則作為校驗(yàn)規(guī)則。那么使用 Prettier 格式化后访圃,使用 ESLint 校驗(yàn)就不會出現(xiàn)對前者的 warning厨幻。

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

方案一實(shí)踐

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

    $ npm install --save-dev prettier-eslint prettier-eslint-cli
    
  2. 運(yùn)行

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

    prettier-eslint 會一次執(zhí)行 prettier 和 eslint --fix 命令否淤。整個流程是:Code ?? prettier ?? eslint --fix ?? Formatted Code悄但。prettier-eslint 的各種參數(shù)請參看 https://github.com/prettier/prettier-eslint-cli

方案二實(shí)踐

方案二的思路主要是在 eslint 的規(guī)則配置文件上做文章石抡,安裝特定的 plugin檐嚣,把其配置到規(guī)則的尾部,實(shí)現(xiàn) prettier 規(guī)則對 eslint 規(guī)則的覆蓋啰扛。

  1. 安裝 plugin:

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

    {
      "extends": [
        ...,
        "已經(jīng)配置的規(guī)則",
    +   "prettier",
    +   "prettier/@typescript-eslint"
      ]
    }
    
    

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

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

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

    看名字應(yīng)該能猜到每個對應(yīng)的是 disable 哪些規(guī)則了吧隐解。

  3. 完成上述兩步可以實(shí)現(xiàn)的是運(yùn)行 eslint 命令會按照 prettier 的規(guī)則做相關(guān)校驗(yàn)鞍帝,但是還是需要分別運(yùn)行 prettier 和 eslint 命令。社區(qū)有一個方案整合了上述兩步煞茫,在使用 eslint --fix 時候帕涌,實(shí)際使用 prettier 來替代 eslint 的格式化功能岩臣。
    安裝:

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

    修改 .eslintrc.*

    {
      "extends": [
        ...,
        "已經(jīng)配置的規(guī)則",
        "plugin:prettier/recommended"
      ]
    }
    
    

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

和VSCode集成使用

上面所有講到的內(nèi)容都是在你寫完代碼去校驗(yàn)的宵膨,使用的是命令行工具架谎。如果你是一個新手,對規(guī)范不是很熟悉辟躏,那么碰到的問題就是寫完代碼運(yùn)行命令行工具后產(chǎn)生海量的 warning谷扣。這個時候改起來真的很打擊積極性。如果能夠在寫的代碼的時候讓編輯器提示就能及時改正了捎琐。自然我們社區(qū)也提供了很多方案会涎,各家的編輯器 Atom、Sublime瑞凑、VSCode 等主流的編輯器都有相關(guān)的插件末秃。我就以 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. 因?yàn)槲沂褂昧?TypeScript 所以 .eslintrc.* 配置項(xiàng)的值和 javascript 有點(diǎn)不一樣,但是原理是一樣的籽御。如果你沒有使用 TypeScript 那么到上面步驟就結(jié)束了练慕。但是 VSCode 的 ESLint 插件沒有天然支持 ts 文件,所以我們還必須自己建立一個設(shè)置文件技掏。在項(xiàng)目根目錄下新建 .vscode/settings.json 文件铃将,內(nèi)容如下:
    {
      "eslint.validate": [
        "javascript",
        "javascriptreact",
        { 
          "language": "typescript",
          "autoFix": true
        },
        { 
          "language": "typescriptreact",
          "autoFix": true
        }
      ]
    }
    

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

強(qiáng)制校驗(yàn)和格式化

講到這里兩個工具配合使用已經(jīng)講好了哑梳,但是這些步驟都依賴于人工自覺劲阎,要做到一點(diǎn)點(diǎn)強(qiáng)制功能,我們就可以用到 husky lint-staged 來在 git commit 前強(qiáng)制代碼格式化和代碼校驗(yàn)鸠真。

  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. 那么在運(yùn)行 git commit 時候悯仙,自動會先去運(yùn)行 prettier --write 格式化代碼,再運(yùn)行 eslint 校驗(yàn)代碼是否符合規(guī)范吠卷。這兩步都通過后才會提交代碼锡垄。如果任何一步失敗,則會停止提交撤嫩。

如果你使用方案一偎捎,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"
  +   ]
  + },
}

參考文獻(xiàn)

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

如果使用的是 TypeScript:

  1. ESLint如何運(yùn)用到TS項(xiàng)目
  2. 如何和Prettier配合使用
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末序攘,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子寻拂,更是在濱河造成了極大的恐慌程奠,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件祭钉,死亡現(xiàn)場離奇詭異瞄沙,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門距境,熙熙樓的掌柜王于貴愁眉苦臉地迎上來申尼,“玉大人,你說我怎么就攤上這事垫桂∈δ唬” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵诬滩,是天一觀的道長霹粥。 經(jīng)常有香客問我,道長疼鸟,這世上最難降的妖魔是什么后控? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮空镜,結(jié)果婚禮上浩淘,老公的妹妹穿的比我還像新娘。我一直安慰自己吴攒,他們只是感情好馋袜,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著舶斧,像睡著了一般欣鳖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上茴厉,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天泽台,我揣著相機(jī)與錄音,去河邊找鬼矾缓。 笑死怀酷,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的嗜闻。 我是一名探鬼主播蜕依,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼琉雳!你這毒婦竟也來了样眠?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤翠肘,失蹤者是張志新(化名)和其女友劉穎檐束,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體束倍,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡被丧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年盟戏,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片甥桂。...
    茶點(diǎn)故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡柿究,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出黄选,到底是詐尸還是另有隱情蝇摸,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布糕簿,位于F島的核電站探入,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏懂诗。R本人自食惡果不足惜蜂嗽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望殃恒。 院中可真熱鬧植旧,春花似錦、人聲如沸离唐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽亥鬓。三九已至完沪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間嵌戈,已是汗流浹背覆积。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留熟呛,地道東北人宽档。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像庵朝,于是被迫代替她去往敵國和親吗冤。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容