# 如何整合ESlint, Prettier, VSCode? ###### tags: `VSCode` `ESlint` `Prettier` `Vue` 先說結論:無法同時使用ESlint和Prettier,ESlint是調整coding的style,Prettier是用來規範coding的嚴謹度,兩者做的事會有衝突。 ### 問題:同時使用ESlint和Prettier,會出現格式衝突 在Vue專案中,想使用[vue/max-attributes-per-line](https://eslint.vuejs.org/rules/max-attributes-per-line.html),但會和Pretter衝突,造成每次存擋時,都無法如預期效果。 expected when formatOnSave: ```htmlmixed <template> <div v-show="test" v-if="on" id="123" class="test"> {{ quote }} <p id="1" class="123"> 1234 </p> </div> </template> ``` actually happened when formatOnSave: ```htmlmixed <template> <div v-show="test" v-if="on" id="123" class="test"> {{ quote }} <p id="1" class="123"> 1234 </p> </div> </template> ``` 查完GitHub的issues和StackOverFlow之後,結論就是如上,關掉vue/max-attributes-per-line或是關掉Prettier,但無論如何兩者都想使用的話,有找到一個lib應該還算堪用。 --- ### 解法 [官方建議](https://prettier.io/docs/en/integrating-with-linters.html#disable-formatting-rules) formatOnSave時,eslint會調整code為我們希望的風格,而semi column和spance等Prettier的工作則透過[prettier-eslint-cli](https://github.com/prettier/prettier-eslint-cli)去完成,prettier-eslint每次只能prettier一行或一個檔案,要使用在整個專案,便需要prettier-eslint-cli。看了下[prettier-eslint的npm](https://www.npmjs.com/package/prettier-eslint),每週下載次數三十幾萬(2020/08時),最新更新在2020/06,且官方文件也有列入,可以放心使用。 共有3個地方需處理: 1. VScode 2. eslintrc.js 3. package.json --- #### VScode 在VScode的setting要調整,如下: 因為我們是要透過eslint去調整code,因此請把editor.formatOnSave關掉: ```javascript "editor.formatOnSave": false ``` 但我們希望每次儲存時可以自動使用eslint: ```javascript "editor.codeActionsOnSave": { "source.fixAll.eslint": true }, ``` 設定希望eslint調整的檔案,因為是用Vue專案,所以有放vue: ```javascript "eslint.alwaysShowStatus": true, "eslint.options": { "extensions": [".html", ".js", ".vue"] }, "eslint.validate": ["html", "vue", "javascript"], ``` 當然也不希望Vetur去format ```javascript "vetur.validation.template": false, "vetur.validation.script": false, ``` --- #### eslintrc.js 不希望將settings和rule都放在package.json中,故在根目錄建立eslintrc.js,若使用vue-cli的話它會幫你內建此檔案。 extends裡代表的是一個大範圍的規範,裡面有許多rules,只要放入`plugin:vue/recommended`,你就可以使用vue風格全部的規範,並且在rules中客製化自己或是團隊的style,不需要逐條設定。recommended是最嚴謹的風格也是最不需動腦的設定,相反的,vue/base是最基本也是最不嚴謹的。在extends中,我們只需要vue和eslint的style,有關prettier的都可以先移除。 parserOptions是因為我們有使用較新的js語法(如es6+),因此需設定在這。 ```javascript module.exports = { root: true, env: { node: true }, extends: [ 'plugin:vue/recommended', 'eslint:recommended', ], parserOptions: { parser: 'babel-eslint' }, rules: { 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 'vue/max-attributes-per-line': [ 'error', { singleline: 1, multiline: { max: 1, allowFirstLine: true } } ] } } ``` --- #### package.json 打開terminal,用npm安裝在專案中的devDependencies `npm install --save-dev prettier-eslint-cli` 確認安裝完成在devDependencies: `"prettier-eslint-cli": "^5.0.0",` 在package.json中的script設定指令 ```javascript { "scripts": { "format": "prettier-eslint \"src/**/*.js\"" } } ``` 由於目前使用的是Vue專案,故修改如下: ```javascript "format": "prettier-eslint --write \"$(pwd)/src/**/*.js\" \"$(pwd)/src/**/*.vue\" [--semi false --single-quote true]" ``` `--write` : 讓prettier-eslint-cli可以直接修改你的檔案,沒有加的話,只會將修改的結果log在terminal上,不管跑幾次你的code實際上都不會改變 `\"$(pwd)/src/**/*.js\" \"$(pwd)/src/**/*.vue\"` $(pwd)是指Pathname of the current Working Directory 要format複數檔案的話,以空格分開,再放上路徑及檔名 `[--semi false --single-quote true]`: option設定的地方,如文件中所寫的prettier-eslint <globs>... [--option-1 option-1-value --option-2],其他設定可以看[這裡](https://github.com/prettier/prettier-eslint-cli#cli-options)或是下指令`prettier-eslint --help` --- #### 測試 create一個vue component ```javascript <template> <div v-show="test" v-if="on" id="123" class="test"> {{ quote }} <p id="1" class="123"> 1234 </p> </div> </template> <script> export default { data () { return { quote: "test" } } }; </script> <style> .a { color: black } </style> ``` 可以看到上面幾個故意打錯不符合先前設定的Prettier規則: "test"沒有使用singleQuate export default結尾放了semicolumn css的black沒有semicolumn 此時在terminal中run: `npm run format`應該會出現類似下圖 ![](https://i.imgur.com/noVshzs.png) 便表示成功讓prettier-eslint幫你使用了prettier且沒有更改eslint調整的code。 ```htmlmixed <template> <div v-show="test" v-if="on" id="123" class="test"> {{ quote }} <p id="1" class="123"> 1234 </p> </div> </template> <script> export default { data() { return { quote: 'test' } } } </script> <style> .a { color: black; } </style> ``` --- 為了讓Prettier和ESlint同時使用,重點是想要符合Vue的style指引,花了不少時間爬文和測試設定,也剛好更了解這兩個套件彼此的關係。 如內容有誤或有其他想法歡迎交流! refference: https://eslint.vuejs.org/user-guide/#installation https://pjchender.github.io/2019/07/26/vue-%E6%95%B4%E5%90%88-vue-style-guide-eslint-%E5%92%8C-vscode/ https://github.com/prettier/prettier-eslint-cli https://github.com/prettier/eslint-plugin-prettier/issues/289 https://eslint.vuejs.org/rules/html-closing-bracket-newline.html