# linter とフォーマッター
## 前回
stylelint のすすめ
https://slides.com/chalkygames123/stylelint
## linter とは
エラーや潜在的なバグを警告するもの
- ESLint (JavaScript)
- stylelint (CSS)
それぞれ自動修正機能を持つ。お互いに、コマンド体系や設定の書き方にある程度の一貫性がある。
コマンドラインツールや gulp プラグイン、 webpack ローダーとして使える。
### 使い方
ESLint:
1. `yarn add -D eslint`
2. `.eslintrc.js` に設定を書く
3. `yarn eslint src` (`src` ディレクトリ以下のすべての `.js` ファイルを lint)
stylelint:
1. `yarn add -D stylelint`
2. `.stylelintrc.js` に設定を書く
3. `yarn stylelint "src/**/*.css"` (`src` ディレクトリ以下のすべての `.css` ファイルを lint)
設定ファイルの形式は、動的にルールを定義できる .js がおすすめ。
## フォーマッターとは
スペースやインデント、改行等のコーディングスタイルを統一するもの
- Prettier (JavaScript, CSS, JSON, YAML, Markdown, etc.)
2018 年 11 月 に HTML のサポートが追加されたが、 XHTML との互換性のために空要素に終端スラッシュが付く。これは将来的にオプションで無効化できるようになる可能性がある: [Add an option to prefer void tags over xml compatible self closing tags. · Issue #5246 · prettier/prettier · GitHub](https://github.com/prettier/prettier/issues/5246)
### 使い方
1. `yarn add -D prettier`
2. `.prettierrc.js` に設定を書く
3. `yarn prettier "**.{json,md}"` (すべての `.json`, `.md` ファイルを フォーマットチェック)
## linter とフォーマッターを併用する
ESLint/stylelint の自動修正機能でもフォーマットは行えるが、フォーマットは Prettier のほうが得意。餅は餅屋。
- ESLint と stylelint には「shareable config」と「プラグイン」という機構があり、それを利用して Prettier のフォーマットルールを統合することができる
- Prettier は公式にそれぞれの shareable config とプラグインを用意してくれている
- ESLint/stylelint の自動修正を実行すると、Prettier のフォーマットルールをもとに修正してくれるようになる
### ESLint
- `yarn add -D eslint-config-prettier`
- `yarn add -D eslint-plugin-prettier`
``` .eslintrc.js
module.exports = {
extends: ['plugin:prettier/recommended']
}
```
### stylelint
- `yarn add -D stylelint-config-prettier`
- `yarn add -D stylelint-prettier` (`-plugin` は付けない)
``` .stylelintrc.js
module.exports = {
extends: ['stylelint-prettier/recommended']
}
```
`stylelint-plugin-prettier` パッケージは個人が開発していたもの。もうメンテナンスされていない。
## lint から特定のディレクトリ/ファイルを除外する
3 つの方法
- `--ignore-pattern` オプション
- e.g. `eslint --ignore-pattern dist .`
- `--ignore-path` オプション
- e.g. `eslint --ignore-path .gitignore .`
- `.eslintignore` および `.stylelintignore` ファイル
- `.gitignore` と同じ記法
## Tips
### lint するファイルを glob パターンで指定する
stylelint と同様、 ESLint も glob パターンが使える
e.g. `eslint src` -> `eslint "src/**/*.js"`
- CLI で指定する glob パターンは、シェルによって解釈されないようクォーテーションで囲う必要がある
- Windows をサポートしないならシングルクォーテーション、するならダブルクォーテーション
- `package.json#scripts` 内では、ダブルクォーテーションはエスケープする (e.g. `"lint:scripts": "eslint \".\""`)
### lint するファイルに dotfiles を含める
ESLint は、デフォルトでは dotfiles (`.` で始まるファイル) を無視する。含めたい場合、CLI では `--ignore-pattern` オプションに `!.*` を指定する。設定ファイルでは `ignorePatterns` オプションに `['!.*']` を指定する。なお、`.eslintignore` に `!.*` を指定しても効果はない。
### 環境変数によってルールを切り替える
> .eslintrc.js
```
const isProd = process.env.NODE_ENV === 'production'
module.exports = {
rules: {
'no-console': isProd ? 'error' : 'off',
'no-debugger': isProd ? 'error' : 'off'
}
}
```
### shareable config の一部だけを使う
e.g. `stylelint-config-recess-order` の `'order/properties-order'` フィールドを引用する
> .stylelintrc.js
```
const stylelintConfigRecessOrder = require('stylelint-config-recess-order')
module.exports = {
rules: {
'order/properties-order': [
stylelintConfigRecessOrder.rules['order/properties-order'],
{
unspecified: 'bottomAlphabetical'
}
]
}
}
```
[stylelint-config-recess-order/index.js at master · stormwarning/stylelint-config-recess-order · GitHub](https://github.com/stormwarning/stylelint-config-recess-order/blob/master/index.js)
## 運用の補助
### pre-commit フック
`husky` と `lint-staged` を組み合わせることで、`git commit` 時に lint とフォーマットチェックを実行することができる
パスしなかった場合はコミットが中断される
`package.json`
```
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.js": [
"eslint"
],
"*.scss": [
"stylelint"
],
"*.{json,md}": [
"prettier -c"
]
}
```
下記のようなケースでは無効:
- `node_modules` が無い場合
- GitHub など、 Web から編集した場合
これらのケースもカバーしたい場合は、 CI を使う。
[Pre-commit Hook · Prettier](https://prettier.io/docs/en/precommit.html)
## 参考記事
[Prettier 入門 ~ESLintとの違いを理解して併用する~ - Qiita](https://qiita.com/soarflat/items/06377f3b96964964a65d)