【Vue.js】ESLintとPrettierでgit commit時にコード整形を行う

# はじめに
複数人での開発になると、人それぞれ書き方が違ったりインデントがバラバラだったりすることがあります。
コーディング規約などを定めることはもちろん重要なことですが
各々宗派があるので、エディタでは自身の書き方で、コミット時にLintとコード整形を実行しよう！

という記事。

# インストール
ESLintをインストールします。
```npm install --save-dev eslint```

Vue.jsでESLintを使うためのプラグインをインストールします。
```npm install --save-dev eslint-plugin-vue```

コード整形をするためのプラグインをインストールします。
```npm install --save-dev eslint-plugin-prettier eslint-config-prettier```

↓コピペ用にどうぞ↓
```npm i -D eslint eslint-plugin-vue eslint-plugin-prettier eslint-config-prettier```

# .eslintrc.jsを作成

```javascript:.eslintrc.js
module.exports = {
  root: true,
  env: {
    browser: true,
  },
  extends: [
    'plugin:vue/essential', 
    "eslint:recommended",
    "plugin:prettier/recommended",
  ],
  plugins: [
    'vue',
    'prettier'
  ],
  rules: {
    'generator-star-spacing': 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
    'arrow-parens': 0,
    'one-var': 0,
    'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
    "vue/html-indent": ["error", 2]
  }
}
```

ESLintのvueプラグインでは.vueファイルのhtml（template）のインデントが整わないため、rulesに記述します。
インデントがスペース2の場合
```"vue/html-indent": ["error", 2]```
となります。

その他のrulesなどは@mysticateaさんの[記事](https://qiita.com/mysticatea/items/f523dab04a25f617c87d)を参考にアレンジしてください。

# package.jsonに記述

scriptsに登録します。

```json:package.json
{
  "scripts": {
    "lint": "eslint --ext .js,.vue src --fix"
  }
}
```

# git commit時にESLintを実行
## インストール

pre-commit lint-stagedをインストール
```npm install --save-dev pre-commit lint-staged```

huskeyをインストール
```npm install --save-dev husky@next```

※<font color="Red">pre-commit, lint-stagedを先にインストールしてからhuskeyをインストールしてください。</font>
同時にインストールするとうまく動きません。同時にインストールしてしまった場合はhuskeyをアンインストールしてから再度インストールしてください。



## package.jsonに記述

```json:package.json
"scripts": {
    "lint": "eslint --ext .js,.vue src --fix",
  },
 "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "*.js": [
      "eslint --ext .js src --fix",
      "git add"
    ],
    "*.vue": [
      "eslint --ext .vue src --fix",
      "git add"
    ]
  }
```

## 実行
```git commit```すると実際にコミットされる前に```eslint```の処理が走ります。
コードの整形が終わると自動的に```git add```されてからコミットされます。

## 全ファイルを対象にコード整形する場合
下記コマンドで実行します。
```npm run lint```

※すべての```.js```ファイル及び```.vue```ファイルに整形がかかるためコンフリクトを起こす可能性があります。実行時は注意が必要です。

# Typescriptを使用している場合
## インストール
tslintと関連プラグインをインストールします。

```npm i -D tslint tslint-plugin-prettier```

## tslint.jsonを作成

```json:tslint.json
{
  "defaultSeverity": "error",
  "extends": [
    "tslint:recommended",
    "tslint-plugin-prettier"
  ],
  "rules": {
    "indent": [true, "spaces", 2],
    "prettier": [true, {
      "tabWidth": 2
    }],
  }
}
```


## package.jsonに記述

```json:package.json
{
  "scripts": {
    "lint": "eslint --ext .js,.vue src --fix",
    "lint:ts": "tslint --fix --format stylish -c tslint.json 'src/**/*.ts'"
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "*.js": [
      "eslint --ext .js src --fix",
      "git add"
    ],
    "*.vue": [
      "eslint --ext .vue src --fix",
      "git add"
    ],
    "*.ts": [
      "tslint --fix --format stylish -c tslint.json 'src/**/*.ts'",
      "git add"
    ]
  }
}
```

## 実行
```git commit```すると実際にコミットされる前に```eslint```の処理が走ります。
コードの整形が終わると自動的に```git add```されてからコミットされます。


# 問題
## 特定のファイルのみコミットする場合
編集したファイルが複数あり、一つのファイルのみを指定してコミットする
例）```git add .```じゃなくて```git add App.vue```
この場合、```git add App.vue``` → ```git commit``` → ```eslint``` → ```git add .```
となるため、App.vue以外の編集されたファイルはeslintを通さずにgit addされてしまいます。
解決策としては、コミット時ではなくプッシュ時(?)にESLintを走らせることで解決できます。
こちらはシェルスクリプトで対応(?)が必要となります。

## htmlのコード整形
htmlに関してはインデントを整えるだけになります。

```html
<div><h1>Title</h1></div>
```
上記コードだと整形後もそのままになります。


# おわりに
コード整形に関してはそのうちvue-cliに標準で搭載されるかもしれませんね...

.eslintrc.jsはとても細かく設定できると感じました。
導入時には一度詳しく調べて設定することをお勧めします。

以上