続・VSCode上でvueファイルに対してESLintとPrettierが快適に動作する設定

2022/10/03 追記
------------

本稿は2020/04/22頃にVue 2+VeturというVSCode機能拡張を使って開発する前提でした。

現在は、Vueは3になりComposition APIが追加されていたり、TypeScriptも使えるようになっていたり、VolarのVSCode機能拡張を使うようになっており、本稿を書いた時から状況が変わっています。

Vue 3になってからの情報はあまりキャッチアップできていないため、快適な設定についてはよくわからないのでまだ書けません。
が、ESLintでLintを行い、Prettierでフォーマットする、というのは変わらないように思えます。（静的検査を環境に依存することなく行うには今も必要だと思います）




元の記事
------------


[以前に投稿した時](https://qiita.com/fukasawah/items/cfff8957f3956850dc7e) から色々変化したのでアップデートを兼ねて。

- VSCodeが`editor.codeActionsOnSave`や`editor.defaultFormatter`をサポートした
- VSCodeのESLint機能拡張がバージョンアップし設定も変わった
  - 詳しくは https://qiita.com/mysticatea/items/3f306470e8262e50bb70
- ESLintはLintに専念し、フォーマッターにPrettierを使うようにした
  - 詳しくは https://qiita.com/soarflat/items/06377f3b96964964a65d

またフォーマッター周りが変化しましたが、これで落ちつくだろうと思います。


## VSCode機能拡張

- Vetur: Vueファイルの検出や補完のために。フォーマット機能は使わない
- ESLint: VSCode操作時にESLintを使ったLintやFormatするために使う

`.vscode/extensions.json`を書いておけばVSCodeでプロジェクトを開いた時に推奨プラグインとして出せます。

```js:.vscode/extensions.json
{
    "recommendations": [
        "octref.vetur",
        "dbaeumer.vscode-eslint"
    ]
}
```

## 設定ファイル

### VSCodeの設定

```js:.vscode/settings.json
{
    // ESLintに対応しているファイルは保存時にESLintによるフォーマットを行う
    "editor.codeActionsOnSave": {
        "source.fixAll.eslint": true
    },
}
```

`source.fixAll`もありますが、違いは以下の通りです。

- `source.fixAll.eslint`: ESLint機能拡張の対象ファイルのみ有効/無効
- `source.fixAll`: 全てのファイルで有効/無効

see: https://github.com/microsoft/vscode-eslint/


### ESLint

Vue cliでTypeScriptプロジェクトで作った時のものをそのまま引用。

``` .eslintrc.js
module.exports = {
  root: true,
  env: {
    node: true,
  },
  extends: [
    'plugin:vue/essential',
    'eslint:recommended',
    '@vue/typescript/recommended',
    '@vue/prettier',
    '@vue/prettier/@typescript-eslint',
  ],
  parserOptions: {
    ecmaVersion: 2020,
  },
  rules: {
    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
  },
};
```

Prettierを使わない場合は prettier がある行をコメントアウトすればよいです。

蛇足ですが、`plugins:['vue']`は書かなくて動くのが気になったのですが、extendsの`plugin:vue/essential`を見て`eslint-plugin-vue`を読んでくれるようです。（要出典）

### Prettier

お好みで。

``` .prettierrc.js
module.exports = {
  trailingComma: 'es5',
  tabWidth: 2,
  semi: true,
  singleQuote: true,
  // https://prettier.io/docs/en/options.html#vue-files-script-and-style-tags-indentation
  vueIndentScriptAndStyle: true,
};
```

`vueIndentScriptAndStyle` はvueの`<script>,<style>`内のインデントを1個入れる機能です（[eslint-plugin-vueのbaseIndent](https://github.com/vuejs/eslint-plugin-vue/blob/master/docs/rules/script-indent.md)のPrettier版という認識）


以上。


補足
----------

### VSCodeのShift+Alt+Fでフォーマットをかけたい

Shift+Alt+Fでフォーマットをかけたい場合は以下も指定する。

``` js:.vscode/settings.json
{
    // ファイルの種類ごとにフォーマッターを指定する
    // 指定しないとどのフォーマッターを使うか確認が出てしまうので明示する必要がある
    "[vue]": {
        "editor.defaultFormatter": "dbaeumer.vscode-eslint"
    },
    "[javascript]": {
        "editor.defaultFormatter": "dbaeumer.vscode-eslint"
    },
    "[typescript]": {
        "editor.defaultFormatter": "dbaeumer.vscode-eslint"
    },
    // Shift+Alt+FでESLint機能拡張のフォーマットを行えるようにする
    "eslint.format.enable": true,
}
```

確認で指定した設定はユーザのローカルのワークスペース設定として記憶してしまうので、この挙動が嫌な場合に予防として設定しておくとよいかもしれない。


### VSCodeのShift+Alt+Fのフォーマットを封じたい

保存で行われるのだからいらないでしょうという場合。

既存のフォーマットの動作とVeturのフォーマット機能の動作を無効にしておく。ESLint機能拡張によるフォーマットのみを行う場合も同様。

```js:.vscode/settings.json
{
    "javascript.format.enable": false,
    "typescript.format.enable": false,
    "vetur.format.enable": false,
}
```


### Veturのフォーマット機能を使わない理由

- VSCodeの機能拡張で動いてるのでコマンドベースのフォーマットができない＝統一できない
- 多分、vueIndentScriptAndStyleに相当する操作ができない


### vueファイル内のフォーマット

上記の設定ファイル通りであればeslint経由でprettierによってvueファイル全体のフォーマットが行われます。

前まではJavaScript部分はESLint、他はVeturのデフォルトのフォーマッターを使っていましたが、これで全部Prettierに寄せることができます。
ただ、Prettierは一部のCSSプリプロセッサに対応できないので適宜確認したほうがよいでしょう。

### HTMLファイルとCSSファイルのフォーマット

HTMLファイルとCSSファイルはESLintの対象にならないため、prettierなどで別途フォーマットを行う必要があります。Lintも同様です。