關於eslint+prettier+husky的配置及說明
一.eslint
eslint它規范的是代碼偏向語法層面上的風格。本篇文章以一個基本的vue項目,來說明eslint+prettier+husky配置項目代碼規范,為瞭更好的描述本文,我恢復瞭vscode的默認設置(即未安裝eslint,prettier等插件,setting中也沒有相關配置)
1.新建一個空的vue2.x項目(不安裝eslint)
vue create eslint-test
2.單獨安裝selint
npm install eslint --save-dev
npx eslint --init
生成.eslintrc.js文件:
module.exports = { "env": { "browser": true, "es2021": true, "node": true }, "extends": [ "eslint:recommended",//繼承Eslint中推薦的(打鉤的)規則項http://eslint.cn/docs/rules/ "plugin:vue/essential"// 此項是用來配置vue.js風格 ], "parserOptions": { "ecmaVersion": 13, "sourceType": "module" }, "plugins": [ "vue" ], "rules": { } };
3.查看這個推薦的默認規則
這裡的規則,寫在後面的會覆蓋前面的,並且rules中的規則最後會覆蓋這裡的,所以我們自定義規則就是寫在rules中,才能覆蓋之前的規則,從而生效。
"extends": [ "eslint:recommended",//繼承Eslint中推薦的(打鉤的)規則項http://eslint.cn/docs/rules/ "plugin:vue/essential"// 此項是用來配置vue.js風格https://eslint.vuejs.org/rules ],
quotes – Rules – ESLint中文
Available rules | eslint-plugin-vue (vuejs.org)
這個默認規則是怎麼生效的呢?舉個例子,我們點進去鏈接,可以看到這個no-debugger是打上瞭對勾(也就是"eslint:recommended")中生效的規則,然後我們再在項目中寫個debugger,然後命令行運行檢查eslint的命令,就會報錯瞭。
項目根目錄執行:
npx eslint --ext .vue src/ 等價於:./node_modules/.bin/eslint --ext .vue src/ --ext:可以指定在指定目錄/文件 .vue:vue文件 src/:在src目錄下匹配
4.自定義規則
Eslint附帶瞭大量的校驗規則,這些規則的值分別有如下規律:
- off | 0 :表示關閉規則。
- warn | 1 :表示將該規則轉換為警告。
- error | 2 :表示將該規則轉換為錯誤。
常見的rules規則,可以看官網:List of available rules – ESLint中文
// "semi": [2, "always"],//語句強制分號結尾 // "quotes": [2, "double"],//引號類型 "" //"no-alert": 0,//禁止使用alert //"no-console": 2,//禁止使用console //"no-const-assign": 2,//禁止修改const聲明的變量 //"no-debugger": 2,//禁止使用debugger //"no-duplicate-case": 2,//switch中的case標簽不能重復 //"no-extra-semi": 2,//禁止多餘的冒號 //"no-multi-spaces": 1,//不能用多餘的空格
當我們這樣自定義配置結尾必須分號之後,再運行檢查,項目中就會報對應的錯:
5.package.json中配置檢查命令行
上文中,我們是手動輸入命令行來檢查代碼是否符合eslint規范的,這樣每次檢查都要輸入一遍,有的人要是記不住這命令怎麼辦?於是可以在package.json的script中寫死這個腳本:
"lint": "eslint --ext .js --ext .jsx --ext .vue src/",
於是,項目根目錄運行npm run lint,實際上就是運行:
npx eslint --ext .js --ext .jsx --ext .vue src/
從而實現代碼的檢查:
6.eslint插件自動檢查規范
難道每次寫完一句代碼,都要npm run lint來檢查下是否符合規范嘛?那樣太麻煩瞭。於是有eslint插件,這裡我用的是vscode,打開插件市場,搜索到eslint,安裝即可:
安裝瞭之後什麼效果呢?就是它會自動檢查你的代碼是否符號規范,並且會在編輯器中標識出來哪裡不符合規范,底下終端處還會羅列出問題:
7.package.json中配置自動修復命令行
比如說上文咱們寫瞭好多這種bug,一個一個手動修復,太麻煩瞭。eslint提供瞭一個–fix的命令行,可以實現自動修復不符合規范的代碼,但是這種修復不是萬能的,官網中說,有這個(扳手)🔧的圖標對應的規則才是可以修復的。
可以看到,debugger這個規則應該是不能修復的,而分號這個是可以自動修復的。
具體的命令行,同樣設置到package.json中:
"lint-fix": "eslint --fix --ext .js --ext .jsx --ext .vue src/"
在根目錄執行這個npm run lint-fix:
可以看到分號的錯誤被修復瞭,而debugger無法自動修復,隻能手動修復。
8.在vscode中配置setting,讓每次保存代碼時自動修復
先不考慮debugger這種隻能手動修復的,在實際寫代碼中,更多時候遇到的是分號啦,單雙引號啦這些可以被自動修復的錯誤,那麼,我們還需要每次去手動敲npm run lint-fix嘛?那同樣效率很低。現在利用vscode的eslint插件我們已經能一寫完代碼,就知道是否符合規范瞭。然而我們還想實現的是每次寫完代碼,按下ctrl+s保存時,它能夠自動修復。
幸運的是,vscode的setting.json能夠幫助我們實現這一點:
在vscode中按快捷鍵ctrl+shift+p,輸入setting,打開setting.json
增加這段配置即可(如果未生效重啟vscode):
//配置保存時按照eslint文件的規則來處理一下代碼 "editor.codeActionsOnSave": { "source.fixAll": true, "eslint.autoFixOnSave" : true, },
可以看到,我一按保存,就自動修復瞭分號的問題。
9.配置eslintignore
有些文件,我們不希望它受eslint管轄,可以在根目錄新建.eslintignore文件,把想要自由的文件或目錄丟進去即可:
- .eslintrc.js
- .prettierrc.js
- babel.config.js
- vetur.config.js
- /node_modules/
10.總結
反思幾個問題:
我們為什麼需要eslint?
因為每個人的代碼習慣不一樣,每個開發人員都需要和他人協作或者項目需要交接給下一代開發者。保持統一的代碼規范,可以極大地提高效率,降低溝通和理解代碼的成本。
既然已經有vscode的eslint插件幫助我們自動檢查和修復代碼瞭,為什麼還需要在pakage.json中配置eslint命令行?
因為vscode是我們自己電腦上的編輯器,我們不能保證另一個人拿到我們的代碼時他也是用vscode的(也許他用記事本?)。就算他用vscode,我們也不能保證他安裝瞭eslint插件。 ,他就可以使用pakage.json的命令行來檢查和修復代碼。因為項目中肯定需要安裝eslint依賴,也肯定有我們配置的.eslintrc.js規則文件,這樣依舊能保證代碼的統一規范。
二.prettier
1.prettier的作用
上文我們配置瞭eslint,它規范的是代碼偏向語法層面上的風格。比如說不能使用console啦,箭頭函數參數必須包裹在括號中啦這些。
而項目中有時候,我們寫代碼刪刪改改,或者是個人的代碼習慣,就有可能出現這樣的代碼:
<script> import HelloWorld from './components/HelloWorld.vue'; export default { name: 'App', components: { HelloWorld } }; </script>
排版很亂,或者寫html時,太長瞭換不換行之類的代碼排版問題,就需要prettier來規范。
也就是說,prettier規范的是代碼偏向於排版層面上的風格。
2.安裝prettier
npm install --save-dev --save-exact prettier
3.使用命令行修復格式化
npx prettier --write src/
可以看到,我原先故意寫亂的代碼,變得整齊瞭。
4.配置自定義的prettier規則
需要在根目錄新建一個文件.prettierrc.js(則需要module.export),如果是.prettierrc(則隻需要json格式):
//此處的規則供參考,其中多半其實都是默認值,可以根據個人習慣改寫 module.exports = { printWidth: 80, //單行長度 tabWidth: 2, //縮進長度 useTabs: false, //使用空格代替tab縮進 semi: false, //句末使用分號 singleQuote: false, //使用單引號 arrowParens: "avoid",//單參數箭頭函數參數周圍使用圓括號-eg: (x) => xavoid:省略括號 bracketSpacing: true,//在對象前後添加空格-eg: { foo: bar } insertPragma: false,//在已被preitter格式化的文件頂部加上標註 jsxBracketSameLine: false,//多屬性html標簽的‘>'折行放置 rangeStart: 0, requirePragma: false,//無需頂部註釋即可格式化 trailingComma: "none",//多行時盡可能打印尾隨逗號 useTabs: false//使用空格代替tab縮進 };
為瞭測試是否生效,我故意把句末是否使用分號寫成瞭false(上文中eslint是需要分號的)。執行npx prettier –write src/,可以看到,分號被取消瞭,但是不滿足eslint規則,報錯瞭:
沖突的問題稍後再說,這裡隻是說明我們配置的.prettierrc.js是生效的。
5.prettier插件保存代碼自動修復
同樣的,我們不可能每寫一行代碼,就運行npx prettier –write src/來美化一次代碼,我們希望保存代碼時,就能夠自動格式化代碼。於是又需要安裝prettier插件。
然後再ctrl+shift+p打開vscode的setting.json文件,添加如下配置:
//prettier可以格式化很多種格式,所以需要在這裡對應配置下 "[html]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[css]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[less]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[vue]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[typescriptreact]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[jsonc]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[typescript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[json]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, //這個設置在ctrl+s的時候,會啟用默認的格式化,這裡是prettier "editor.formatOnSave": true
這時候按保存代碼,會發現在閃動,依舊是報eslint的錯:
這是因為eslint的規則和prettier沖突瞭,當我們保存的時候。先執行eslint的自動修復,於是分號會加上。然後又執行prettier的修復,分號又去除,這就導致閃動,到頭來還是報eslint的錯。這裡主要是體現prettier在保存代碼時能夠自動修復,沖突的問題依舊先放到後面說。
6.讓編譯器能報prettier的錯
到目前為止,對於prettier,我們還無法查看哪裡不符合規則,而隻是通過自動修復來規范代碼風格。現在我們想像eslint一樣,代碼一寫,如果不符合,就出現紅色的波浪線提示哪裡有問題。
這個要怎麼實現呢?可以利用eslint的報錯,把prettier當成eslint的插件註入eslint中,讓eslint來報這個錯(實際上還是vscode的eslint實現的)
安裝依賴:
npm i -D eslint-plugin-prettier
然後再在.eslintrc.js 配置文件中添加這個配置,意思就是使用 eslint 報prettier的錯誤:
// .eslintrc.js { "plugins": ["prettier"], "rules": { "prettier/prettier": "error" } }
這樣設置後,我故意把代碼排版變亂:
可以註意到,編輯器已經可以同時報eslint和prettier的錯誤瞭。
這時保存下代碼,除瞭沖突的部分,都會被自動修復。
接下來可以著手解決這兩傢夥沖突的問題瞭。
7.解決eslint和prettier的沖突問題
先說一個事情,其實上文中我反復說的沖突。並不是真正意義上的eslint和prettier的沖突。因為上文的沖突,eslint的規則設置在.eslintrc.js的rules中,prettier的設置在prettierrc.js中,這兩者都是我們開發者自己設置的!這分明是前端程序員自己傻逼,給編輯器下絆子!(這麼說大傢別打我,我還年輕還沒娶媳婦……)
我解釋一下沖突的緣由,就能夠理解我為啥這麼說瞭。
首先,我們是安裝瞭eslint。
那這個eslint要能校驗代碼,它肯定是有一套默認的代碼規范的。
上文中第一章節第三點說過
"extends": [ "eslint:recommended",//繼承Eslint中推薦的(打鉤的)規則項http://eslint.cn/docs/rules/ "plugin:vue/essential"// 此項是用來配置vue.js風格 ],
這裡的eslint:recommended就是這套默認規則,當然有時候我們不用這套規則。會用其他成熟的規則方案例如Airbnb 規范。比如這裡我就額外引入瞭plugin:vue/essential,作為vue文件的規范。
這裡需要再強調一點,這個extends數組中的規則,後面的會覆蓋前面的,也就是vue/essential會覆蓋掉recommended中的重復部分。
並且這裡的規則是由安裝依賴引入的,存放在node_modules文件夾中,也就是為瞭保證其他開發人員代碼一致,這裡面的文件是不允許改動的。
所以說eslint和prettier的沖突問題,其實說的是這些依賴引入的規則和prettier的沖突!
而不是你自己配置的eslint中的rules和你自己配置的prettier沖突。
為瞭證明我的說法,我去node_modules/eslint/conf/eslint-recommended.js增加一個eslint規則:(這個文件中設置的規則上文說過是官網中打瞭勾的部分,quotes不在默認規則裡,為瞭好理解,我手動添加一個)
現在eslint中的配置是這樣,我把自定義的配置關閉掉,prettier中是這樣。即eslint默認配置需要雙引號,prettier設置需要單引號,兩者是沖突的:
這時候我再按ctrl+s保存代碼,就可以看到兩者沖突瞭。(修改後未生效,需要重啟vscode):
網上說的解決沖突的依賴安裝一下:
npm i -D eslint-config-prettier
把prettier設置的規則添加到extends數組中:
extends: [ 'eslint:recommended', //繼承Eslint中推薦的(打鉤的)規則項http://eslint.cn/docs/rules/ 'plugin:vue/essential', // 此項是用來配置vue.js風格 'prettier',//把prettier中設置的規則添加進來,讓它覆蓋上面設置的規則。這樣就不會和上面的規則沖突瞭 ],
這樣一來,就讓在它之前的所有可能會與 prettier 規則存在沖突的 eslint規則失效,並使用 prettier 的規則進行代碼檢查。
接著,在項目中ctrl+s報錯代碼,可以看到報錯消失,變成瞭prettier設置的單引號瞭:
這才是真正意義上的解決沖突。
接下來,再來說rules中的沖突怎麼辦?它的優先級要高於extends中的規則,而extends中沖突的規則已經被prettier搞失效瞭,你又在rules中再定義,於是又會和prettier中產生沖突。
也就是說,上文解決沖突隻會解決extends中的沖突。不會解決rules中的沖突!
那我們這種沖突應該怎麼解決?
- 第一種方案:把自己想要的規則配置成npm包發佈,然後引入到這個extends數組中。
- 第二種方案:relus中的配置和prettier中的保持一致即可。
8.讓沒有安裝prettier的項目也能代碼格式化
有的時候,我們的項目並沒有配置prettier,而我們希望在vscode中可以在保存代碼時美化代碼。就可以在ctrl+shift+p打開setting.json配置prettier規則:
/* prettier的配置 */ "prettier.printWidth": 80, // 超過最大值換行 "prettier.tabWidth": 2, // 縮進字節數 "prettier.useTabs": false, // 句尾添加分號 "prettier.singleQuote": false, // 使用單引號代替雙引號 "prettier.proseWrap": "preserve", // (x) => {} 箭頭函數參數隻有一個時是否要有小括號。avoid:省略括號 "prettier.bracketSpacing": true, // 在對象,數組括號與文字之間加空格 "{ foo: bar }" "prettier.endOfLine": "auto", // 結尾是 \n \r \n\r auto "prettier.eslintIntegration": false, //不讓prettier使用eslint的代碼格式進行校驗 "prettier.htmlWhitespaceSensitivity": "ignore", "prettier.ignorePath": ".prettierignore", // 不使用prettier格式化的文件填寫在項目的.prettierignore文件中 "prettier.jsxBracketSameLine": false, // 在jsx中把'>' 是否單獨放一行 "prettier.jsxSingleQuote": false, // 在jsx中使用單引號代替雙引號 "prettier.parser": "babylon", // 格式化的解析器,默認是babylon "prettier.requireConfig": false, // Require a 'prettierconfig' to format prettier "prettier.stylelintIntegration": false, //不讓prettier使用stylelint的代碼格式進行校驗 "prettier.trailingComma": "none", // 在對象或數組最後一個元素後面是否加逗號(在ES5中加尾逗號) "prettier.tslintIntegration": false, "prettier.arrowParens": "avoid"
9.總結
反思問題:
既然vscode中設置瞭pettier(上文第八點),已經能夠格式化代碼瞭,還要安裝prettier依賴,去配置格式。
原因和eslint中一樣,vscode中配置的,其他人也許不用vscode,也許安裝瞭vscode,但是沒有在setting.json中設置規范。而項目讀取prettier規范時有一個優先級的,如果在根目錄找到瞭.prettier文件,則不會去查找setting.json中的規則瞭。隻有找不到.prettier文件時,我們配置在setting.json中的規則才會生效。
三.提交代碼時eslint校驗
1.husky
為瞭保證每次提交的 git 代碼是正確的,為此我們可以使用 eslint 配合 git hook, 在進行git commit 的時候驗證eslint規范
如果 eslint 驗證不通過,則不能提交。
我們需要安裝一個 git 的 hook 工具 – husky (我剛開始安裝的是最新版本,發現沒有生效,回退後才生效)
npm install [email protected] --save-dev
然後在package.json中增加配置:
"husky": { "hooks": { "pre-commit": "echo 'husky' && npm run lint" } }
意思是在進行 git commit 的時候 先去執行 pre-commit 裡面的命令 : 我們在這裡輸出 husky 並且執行 npm run lint (我們在上文第一章,第5點加上的驗證eslint的命令)
如果eslint驗證通過瞭,則會進行commit 操作,否則會報eslint的錯誤提示。
生效的標志是項目的.git/hooks目錄下,會生成一堆文件,原本是隻有pre-commit.sample這類文件,等husky安裝完成,會多出pre-commit等文件。
再運行git commit命令,就會檢查代碼瞭。
2.lint-staged
如果這是一個新項目以上的就已經滿足要求瞭,但是如果拿到的項目是一個老項目呢,別人開發瞭很久,這個時候加入再加入 eslint 規則,全局去檢查,會發現一堆報錯信息。這個就慌瞭。修改可能帶來其他問題。
為瞭解決這種問題,我們就需要引入 lint-staged
lint-staged 的作用是隻對 git add 緩存區的代碼進行 eslint 代碼規范校驗。這樣就避免瞭全局校驗的問題。你修改瞭上面代碼,你就提交瞭什麼代碼,其他代碼不做 eslint 校驗。
npm install --save-dev lint-staged
在 package.json 中添加:
"lint-staged": { "src/**/*.{css,scss,less}": [ "npm run lint", "git commit" ], "src/**/*.{js,vue}": [ "npm run lint", "git commit" ] }
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- VSCode中 Eslint 和 Prettier 沖突問題最新解決方法
- vscode配置備份的操作代碼
- vue基礎ESLint Prettier配置教程詳解
- Vue3後臺管理系統之創建和配置項目
- vscode 配置eslint和prettier正確方法