Vscode使用時にVueの整形ルールがごっちゃになるのをどうにかしたい

# はじめに

vscodeでvueの開発をしているときに、しばしばコード整形ルールが競合を起こしておかしな形で整形されエラーや警告だらけになってしまう。

自分の場合、慣例的に[Google JavaScript Style](https://google.github.io/styleguide/jsguide.html)を採用しているので更にややこしいことになってしまっている。

特に困るのが以下の問題である：

* シングルクオートにならない
* 配列の末尾にカンマが入らない
* 行の終わりのセミコロンが消える
* `<template>`内のタグの属性が同じ行になってしまう

## 結論

結論から先にいうと、vscodeのprettierがeslintの値を読まないのが原因だった。eslintの`prettier/prettier`の値と同じ内容の.prettierrc.jsを作成することで解決できた。

`<template>`タグ内の整形ルールがおかしいのはprettierのバグのようなのでoffで無効化し、eslint-plugin-vueのルールを採用するようにする。（参考：[prettier not fixing vue/max-attributes-per-line](https://github.com/prettier/eslint-plugin-prettier/issues/94#issuecomment-642336945)）

なお、vueのバージョンが新しくなってエラー扱いになるのは嫌なのでvueのコード整形ルールは`vue3-recommended`を採用。vue3では`filters`が`methods`と統合され非推奨になるので注意。

```sh
npm install -D eslint-plugin-vue@next eslint-config-google
```

### 設定ファイルを作成する場合

```js:.eslintrc.js
module.exports = {
  root: true,
  env: {
    node: true,
  },
  extends: [
    'google',
    'plugin:vue/vue3-recommended',
    'eslint:recommended',
    '@vue/prettier',
  ],
  parserOptions: {
    parser: 'babel-eslint',
  },
  plugins: ['strict-vue', 'prettier'],
  rules: {
    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    quotes: ['error', 'single'],
    'prettier/prettier': [
      'error',
      {
        htmlWhitespaceSensitivity: 'ignore',
        semi: true,
        singleQuote: true,
        trailingComma: 'all',
      },
    ],
    'vue/max-attributes-per-line': 'off',
  },
};
```

```js:.prettierrc.js
module.exports = {
  htmlWhitespaceSensitivity: 'ignore',
  semi: true,
  singleQuote: true,
  trailingComma: 'all',
};
```

### package.jsonに仕込む場合

以下の行を追加する。

```json
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "google",
      "plugin:vue/vue3-recommended",
      "eslint:recommended",
      "@vue/prettier"
    ],
    "parserOptions": {
      "parser": "babel-eslint"
    },
    "plugins": [
      "strict-vue",
      "jsdoc",
      "prettier"
    ],
    "rules": {
      "prettier/prettier": [
        "error",
        {
          "htmlWhitespaceSensitivity": "ignore",
          "semi": true,
          "singleQuote": true,
          "trailingComma": "es5",
          "bracketSpacing": false,
          "printWidth": 80
        }
      ],
      "vue/max-attributes-per-line": "off"
    }
  },
```

[Vetur](https://github.com/vuejs/vetur)は推奨プラグインになっているが、コード整形にprettierを使う場合は外したほうがいいようである。


## おまけ

さて、vueのプロジェクトをつくったときに整形ルールにしばしば以下の行が追加される。

```js:.eslintrc.js
    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
```

しかし、要はプロダクションモードのときに`console.log()`が表示されないようにすればいいのでわざわざルールとして入れる必用はないと思う。

そこで、[前回](https://qiita.com/logue/items/2b744cb1091da83021ab)使った[TerserPlugin](https://webpack.js.org/plugins/terser-webpack-plugin/)を使って圧縮し、同時に`console.log()`の削除を行うようvue.config.jsを修正する。

```sh
npm install -D terser-webpack-plugin
```

```js:vue.config.js
const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
  configureWebpack: {
    // ...省略
    optimization: {
      minimize: process.env.NODE_ENV === 'production',
      minimizer: [
        new TerserPlugin({
          terserOptions: {
            ascii_only: true,
            compress: { drop_console: true },
            mangle: true,
            ecma: 6,
            output: { comments: false, beautify: false },
          },
        }),
      ],
    },
  },
  // ...省略
};
```

### 圧縮率の比較

|               |圧縮前 |デフォルト|Terser |
|:--------------|------:|--------:|------:|
|app.js         | 191 kB|    11 kB|  11 kB|
|chunk-vendor.js|8481 KB|   257 kB| 252 kB|

デフォルトの圧縮プログラムよりも1.9%容量が少なくなりました。（Terserの設定を変えればもう少し削れるかも）