# 如何整合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