前提
本文并不單獨(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。這個時候有兩個解決方案:
- 運(yùn)行 Prettier 之后愿待,再使用 eslint --fix 格式化一把浩螺,這樣把沖突的部分以 ESLint 的格式為標(biāo)準(zhǔn)覆蓋掉,剩下的 warning 就都是代碼質(zhì)量問題了仍侥。
- 在配置 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í)踐
-
安裝 prettier-eslint(Tip:所有方案前提是你已經(jīng)安裝 eslint 和 prettier 相關(guān)包):
$ npm install --save-dev prettier-eslint prettier-eslint-cli
-
運(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ī)則的覆蓋啰扛。
-
安裝 plugin:
$ npm install --save-dev eslint-config-prettier
-
在 .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ī)則了吧隐解。
-
完成上述兩步可以實(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 為例:
-
下載 ESLint Extension
vscode-eslint-extension.png 配置 .eslintrc.*
module.exports = {
parser: '@typescript-eslint/parser',
extends: [
'plugin:@typescript-eslint/recommended',
'prettier/@typescript-eslint',
'plugin:prettier/recommended'
],
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module'
},
// 其他配置
};
- 因?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)鸠真。
-
安裝
$npm install --save-dev husky lint-staged
-
修改 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" + ] + }, }
那么在運(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)
- https://eslint.org/
- https://prettier.io/
- https://restishistory.net/blog/whats-the-difference-between-eslint-and-prettier.html
如果使用的是 TypeScript: