はじめに
今までeslintやprettierの恩恵を受けながら具体的な設定や使い分けを理解していなかったので、改めて調べてみました。
対象
- 設定がよくわからないままeslint/prettierの恩恵を受けている
- eslintだけでなくprettierも導入したい
実際のコードはこちらで確認できます。
前提
$ yarn eslint -v
v5.6.1
$ yarn prettier -v
1.14.3
eslintとprettierをなぜ使うのか?
詳しくこの記事に載っている。
まとめると、eslintは構文チェックとコードフォーマットの機能はあるが、コードフォーマットに関してはprettierの方が優れている。そのためeslintは構文チェッカーとして、prettierはコードフォーマッターとして役割分担して使うことで両者のいいとこ取りができる。
問題は上記のようにeslintにもコードフォーマットの機能があるため、prettierとフォーマットルールが競合する可能性があることで、それぞれただ設定するのではなく、競合しないような設定にすることを注意する必要がある。
eslintの設定
eslintのインストール
$ yarn add -D eslint
eslintの初期設定。質問に答えていくことで設定ファイルができる。
もちろん自分で直接、設定ファイルを作ってもいい。
$ yarn eslint --init
? How would you like to configure ESLint? Answer questions about your style
? Which version of ECMAScript do you use? ES2018
? Are you using ES6 modules? Yes
? Where will your code run? Browser
? Do you use CommonJS? Yes
? Do you use JSX? Yes
? Do you use React? No
? What style of indentation do you use? Spaces
? What quotes do you use for strings? Single
? What line endings do you use? Unix
? Do you require semicolons? Yes
? What format do you want your config file to be in? JavaScript
'The config that you've selected requires the following dependencies:
eslint-plugin-react@latest
Successfully created .eslintrc.js file
Done in 41.01s.
// .eslintrc.js
module.exports = {
"env": {
"browser": true,
"commonjs": true,
"es6": true
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 2018,
"sourceType": "module"
},
"rules": {
"indent": [
"error",
4
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
]
}
};
eslintの設定プロパティ
parserOptions
https://eslint.org/docs/user-guide/configuring#specifying-parser-options
JavaScriptのパーサーに対するプロパティ。パーサー自体は、parser
プロパティで指定できる。
ECMAScriptのバージョンやJSXの利用有無などを指定することができる。
ちなみにReactの使うJSXはJSXオプションをtrue
にするだけでなく、eslint-plugin-reactも利用する必要がある。
Please note that supporting JSX syntax is not the same as supporting React.
React applies specific semantics to JSX syntax that ESLint doesn’t recognize.
We recommend using eslint-plugin-react if you are using React and want React semantics.
module.exports = {
...
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 2018,
"sourceType": "module"
},
...
};
plugins
https://eslint.org/docs/user-guide/configuring#configuring-plugins
外部が提供するプラグインをインストールした上で、指定することで利用可能になる。あとで設定する。
globals
https://eslint.org/docs/user-guide/configuring#specifying-globals
no-undefルールが有効化されていると、そのファイルでは使われているが、定義されていない変数は警告が出る。
そのためグローバル変数もそのエラー対象になってしまうので、globalsプロパティに指定してあげると警告が出なくなる。
また上書き可能の場合はtrue
、読み取り専用の場合はfalse
をつけてあげることで指定できる。
module.exports = {
...
"globals": {
"require": false,
"module": false
}
};
extends
https://eslint.org/docs/user-guide/configuring#extending-configuration-files
extendsに追加することでrulesを拡張することができる。
具体的には、以下の振る舞いで拡張される。
- ルールの追加
- 同じルールの重複するオプションだけ上書き
- 同じルールのオプション全てを上書き
eslint:recommended
はeslintの推奨するルールが追加される。また、各種プラグインもextend用のルールを用意しているので、それも指定することで使うことができる。
これもあとで設定を追加する。
rules
https://eslint.org/docs/user-guide/configuring#configuring-rules
eslintがlintとして適用するルールを追加したり、上書きしたりできる。必ずしも記述されているものが全てというわけではない。
それぞれのルールに対して、以下のオプションを指定して有効化どうかを設定できる。
- off or 0 : ルールの無効化
- warn or 1 : 警告を出すだけ
- error or 2 : エラーをだし、Exit Code 1を返す
module.exports = {
...
"rules": {
"indent": [
"error",
4
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
]
}
};
Reactとflowに対する設定
babel-eslintパーサーを使う
eslintの標準パーサーだと、babelがトランスパイルするes6以上のJavaScriptやflowによる型宣言に対応できないことがある。
それに対応したパーサーを使う。
https://eslint.org/docs/user-guide/configuring#specifying-parser
$ yarn add -D babel-eslint
// .eslintrc.js
module.exports = {
"parser": "babel-eslint",
...
};
React, flowのrulesを追加する
reactとflowを使っている場合。
以下のプラグインがないとparseに失敗する。
$ yarn add -D eslint-plugin-react eslint-plugin-flowtype
また上記プラグインはReact, flow用のruleも利用できるようになっているので、extendsで追加する。
// .eslintrc.js
module.exports = {
"parser": "babel-eslint",
"env": {
"browser": true,
"commonjs": true,
"es6": true
},
"extends": [
"eslint:recommended",
"plugin:react/recommended", // 追加
"plugin:flowtype/recommended" // 追加
],
...
"plugins": [
"react", // 追加
"flowtype" // 追加
],
...
};
webpackでビルド時にeslintをかける
webpackでeslintのチェックをできるようにする。そうすることで毎回eslintのチェックコマンドを実行しなくてもビルドする際に、チェックされるので手間が省ける。
$ yarn add -D eslint-loader
const path = require('path');
module.exports = {
...
module: {
rules: [
{
test: /\.js$/,
use: [
{
loader: 'babel-loader',
options: {
"presets": [
'@babel/preset-env',
'@babel/preset-react',
'@babel/preset-flow'
]
}
},
{
loader: 'eslint-loader' // 追加
}
],
exclude: [/node_module/]
}
]
},
...
};
prettierの設定
prettierの導入
$ yarn add -D prettier
eslintとのルールの競合の解消
競合するルールを調査し、競合するeslintのルールを無効化する
eslint-config-prettierで競合するeslintのルールを無効化することができる。
$ yarn add -D eslint-config-prettier
READMEにあるように、他のextendsされたルールを上書いて無効化するために、extendsの配列の最後に追加する。
exntendsは配列の左から順番に適用されるので、最後にprettier関連のルールを追加しないと他のルールを上書きできないため。
module.exports = {
...
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:flowtype/recommended",
"prettier", // 追加(prettier関連のルールは最後に追加する, eslintの競合ルールを無効化)
"prettier/flowtype", // 追加(eslint-plugin-flowtypeを無効化)
"prettier/react" // 追加(eslint-plugin-reactを無効化)
],
...
};
また、eslint-config-prettier-check
にeslintrcの内容を渡すことで、競合しているルールをチェックできる。
$ ./node_modules/.bin/eslint --print-config . | ./node_modules/.bin/eslint-config-prettier-check
The following rules are unnecessary or might conflict with Prettier:
- flowtype/boolean-style
- flowtype/generic-spacing
- flowtype/space-after-type-colon
- flowtype/space-before-generic-bracket
- flowtype/space-before-type-colon
- flowtype/union-intersection-spacing
- indent
- no-extra-semi
- no-mixed-spaces-and-tabs
- semi
The following rules are enabled but cannot be automatically checked. See:
https://github.com/prettier/eslint-config-prettier#special-rules
- no-unexpected-multiline
- quotes
prettierのルールをeslintrcで指定できるようにする
次に、eslint-plugin-prettierで、prettierのルールをeslintのルールとして追加することが可能になる。
$ yarn add -D eslint-plugin-prettier
同様にextendsにはprettier関連のルールが最後になるようにする。
https://github.com/prettier/eslint-plugin-prettier#installation
Then you need to add plugin:prettier/recommended as the last extension in your .eslintrc.json:
module.exports = {
...
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:flowtype/recommended",
"plugin:prettier/recommended", // 追加
"prettier",
"prettier/flowtype",
"prettier/react"
],
...
"plugins": [
"react",
"flowtype",
"prettier" // 追加
],
"rules": {
"prettier/prettier", // 追加
...
}
};
改めて競合するルールを調べてみる。
$ ./node_modules/.bin/eslint --print-config . | ./node_modules/.bin/eslint-config-prettier-check
The following rules are unnecessary or might conflict with Prettier:
- indent
- semi
The following rules are enabled but cannot be automatically checked. See:
https://github.com/prettier/eslint-config-prettier#special-rules
- quotes
だいぶ減ったが、それでも残った不要なルールの削除と自動でチェックされないルールの設定をする。
module.exports = {
...
"rules": {
"prettier/prettier": ['error', { "singleQuote": true }],
"linebreak-style": [
"error",
"unix"
]
}
};
これで競合も解消された!
$ ./node_modules/.bin/eslint --print-config . | ./node_modules/.bin/eslint-config-prettier-check
No rules that are unnecessary or conflict with Prettier were found.