VSCodeでのNuxt開発環境を整える（ESLint, Prettier）


# 記事の趣旨
Nuxtによるチーム開発体験の向上のために、ESLintやPrettierの設定と、VSCodeとの連携について調べました。

基本的には、nuxt-create-appによるアプリ作成時のテンプレートを生かしつつ、下記のGitHubの設定例を参考にさせていただきました。

https://github.com/chrisvfritz/vue-enterprise-boilerplate

設定等に関して間違っている部分がありましたら、コメントでご教授ください。

# 環境

- Nuxt: 2.14.6
- create-nuxt-app: 3.4.0

# create nuxt app

作成時に以下のように設定しました。

- language: TypeScript
- Linting tools:
  - ESLint（JSコード解析）
  - Prettier（コード整形）
  - Lint staged files（コミットする前に自動解析）
  - StyleLint（CSSコード解析）

# ESLintとPrettier

**2021/7/18 追記**

```
2021/7/18時点で最新のcreate-nuxt-app:3.7.0で試したところ、 下記の問題は解消されていたため、設定変更は不要になります。
```

上記の設定によりインストールされる、`eslint-plugin-prettier` は、ESLint実行と一緒にPrettierによる整形も行うというプラグインなのですが、2020年9月には、非推奨になっているとのことです。

参考: [Prettier と ESLint の組み合わせの公式推奨が変わり plugin が不要になった](https://blog.ojisan.io/prettier-eslint-cli)

理由としては、Prettierは本来、コード整形について考えなくても良くするためのものなのに、このプラグインにより、コード記載中に、赤い波線がたくさん出てきて、邪魔であるということや、速度の問題があるようです。

そのため、`npm rm eslint-plugin-prettier` で削除し、.eslintrc.jsを下記のように変更しました。

```js:.eslintrc.js
module.exports = {
  root: true,
  env: {
    browser: true,
    node: true
  },
  extends: [
    '@nuxtjs/eslint-config-typescript',
    'prettier',
    'prettier/vue',
    // 'plugin:prettier/recommended', // ←削除
    'plugin:nuxt/recommended'
  ],
  plugins: [
    // 'prettier' // ←削除
  ]
}
```

ちなみに、上のextends内の'prettier'という部分は、ESLintとPrettierのルールの競合を防ぐために必要な設定です。

また、typescript-eslintと、通常のeslintで、ルールが重複している部分が見られたため、.eslintrc.jsにとりあえず以下のルールを設定しました。

```js:.eslintrc.js
module.exports = {
  // …
  rules: {
    'no-unused-vars': 'off',
    '@typescript-eslint/no-unused-vars': 'error'
  }
}
```

# Prettier

設定は、デフォルトのsemiとsingleQuoteのルールに加えて、trailingCommaをnoneにしました。（一般的にどちらが良いのかは分かりません）

```json:.prettierrc
{
  "semi": false,
  "singleQuote": true,
  "trailingComma": "none"
}
```

また、ignoreするファイルを、`.prettierignore`に設定しました。

```:.prettierignore
/node_modules/**
/.nuxt/**
package-lock.json
```

# StyleLint

StyleLintは、CSSのコードのエラーをチェックしたり、整形してくれるlinterです。例えば、 `padding: 0px;` → `padding: 0;` のように統一されます。特に設定は変更していません。

# npm scriptsの設定

コマンドで解析をかけたり、自動修正ができるように、npm scriptsを設定しました。

```json:package.json
  "scripts": {
    "lint:prettier": "prettier -c .",
    "lint:js": "eslint --ext .js,.ts,.vue --ignore-path .gitignore .",
    "lint:style": "stylelint **/*.{vue,css,scss} --ignore-path .gitignore",
    "fix": "npm run lint:prettier -- --write; npm run lint:js -- --fix; npm run lint:style -- --fix",
  }
```

コマンド実行時に、lintのエラーがあると、`npm ERR!`というnpmのエラーが表示されてしまうのですが、`npm run lint:js -s` のように`-s`オプションをつけると、表示されなくなりました。

# Lint Stagedの設定

Lint Stagedは、git commit時に、addされたファイルに対して自動でlinterを走らせて、失敗したらコミットを中止したり、自動修正してコミットしたりということができます。

```json:package.json
{
  "lint-staged": {
    "*.{js,ts,vue,json}": "prettier -c",
    "*.{js,ts,vue}": "eslint",
    "*.{css,scss,vue}": "stylelint"
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
```

### （バグに注意？）

同じファイル内で、部分的に変更がaddされた状態で、コミット時にlintエラーがあった場合、addされていなかった変更が消えてしまうというバグが発生しました。

このバグはかなり前のバージョンで対応済みとされていたようなのですが、最近のバージョンであるlint-staged v10.4.0で発生しました。

2020/11/8時点での最新バージョンの10.5.1に上げると、バグは再現されなくなりましたが、一応注意が必要そうです。

# VSCodeでさらに便利に

ここまでで導入した各linterに対応するVSCodeの拡張機能を使用することで、セーブ時に自動修正することなどができるようになります。

- dbaeumer.vscode-eslint
- esbenp.prettier-vscode
- stylelint.vscode-stylelint

上記の拡張機能をインストールして、プロジェクトルートの.vscodeディレクトリ内に、以下のようなsettings.jsonを作成します。

```jsonc:settings.json
{
  // 以下でSave時の動きを設定
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true,
    "source.fixAll.stylelint": true
  },
  // 以下でVSCodeの他の機能によるフォーマットとの競合を防ぐ
  "vetur.format.enable": false,
  "html.format.enable": false,
  "vetur.validation.template": false,
  "javascript.format.enable": false,
  "json.format.enable": false,
  "vetur.validation.script": false,
  "css.validate": false,
  "scss.validate": false,
  "vetur.validation.style": false
}
```

（ESLintは、初回だけ起動を承認する必要がありました。）

## 拡張機能のおすすめを共有

`.vscode` に以下のように設定ファイルを作成することで、プロジェクトをGit CloneしたメンバーがVSCodeで開いた時に、おすすめの拡張機能として、表示してくれます。

```json:.vscode/extensions.json
"recommendations": [
    "dbaeumer.vscode-eslint",
    "esbenp.prettier-vscode",
    "stylelint.vscode-stylelint",
]
```

## コードスニペット

VueのSFCを書く際のテンプレートをスニペットとして登録することで、とても便利になります。

```json:.vscode/_sfc_blocks.code-snippets
{
  "script": {
    "scope": "vue",
    "prefix": "script:type",
    "body": [
      "<script lang=\"ts\">",
      "import { defineComponent } from '@nuxtjs/composition-api'",
      "export default defineComponent({",
      "\t${0}",
      "})",
      "</script>"
    ],
    "description": "<script>"
  },
  "template": {
    "scope": "vue",
    "prefix": "template",
    "body": ["<template>", "\t${0}", "</template>"],
    "description": "<template>"
  },
  "style": {
    "scope": "vue",
    "prefix": "style",
    "body": ["<style lang=\"scss\" scoped>", "${0}", "</style>"],
    "description": "<style lang=\"scss\">"
  }
}
```

今回は、@nuxtjs/composition-apiというライブラリを使うため、`<script>`の部分は上記のように設定しました。
これで、「sc」くらいまで打つだけで、以下の定型文を補完することができます。

```vue
<script lang="ts">
import { defineComponent } from '@nuxtjs/composition-api'
export default defineComponent({
  
})
</script>
```

# 感想

まだ構築したばかりで感触は分かりませんが、自動でチーム内でコードのスタイルや質を合わせることができるメリットは大きそうです。

htmlのタグ内の改行など、かえって見づらくなってしまう部分があったり、改善すべき点があるので、より良い開発のためにアップデートしていきたいです。

2021/7/18追記

```
構築当初は、eslintとprettier周りの設定で修正が必要な点が多かったですが、create-nuxt-appのアップデートにより問題が解消されて、ほぼ設定を変更せずに利用できるようになっていました。

npm scriptsも設定しましたが、チームメンバーがvscodeを使用している前提であれば、利用する機会はありませんでした。
```