【概要】

eslint, prettierの設定はどちらが効いているのかわかりにくい上に、vscodeのバージョンが上がって(おそらくv2.0.4から)から非推奨になった設定が出てきて、尚更わかりにくくなってしまったので整理。

ESLintとPrettierを合わせて使用する設定

今までよく比較されていた設定の方針を大きく分けると

  1. Prettierでフォーマットを行った後に eslint --fixを実行する。
  2. Prettierのフォーマットルールで eslint --fix を実行する。

の2通りだった。

Prettierによると今は2が推奨されているので、2のやり方で行う。1の方がメリットもあるのかもしれないが、この辺は決めの問題だと思うが、一度決めた方針を変えずにプロジェクトを続けたいので、推奨通りに設定する。

これだけでOK。1, 2両方が適用される。

// .eslintrc.jsmodule.exports = {
env: {
browser: true,
es6: true,
node: true,
},
extends: ['eslint:recommended', 'plugin:prettier/recommended'],
globals: {
Atomics: 'readonly',
SharedArrayBuffer: 'readonly',
},
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
},
rules: {
// フォーマットの設定はここでは行わない。全て.prettierrc.jsで行う。
'no-unused-vars': 'warn',
rules: {
// フォーマットに関するルールは.eslintrc.jsで行う
'no-unused-vars': 'warn',
// indent: ["error", 2], ←削除する
//'linebreak-style': ['error', 'unix'],←削除する
// quotes: ["error", "single"], ←削除する
// semi: ["error", "always"],←削除する
},
};

eslintのrulesからフォーマットに関する内容は削除し、フォーマットに関するルールはprettierで指定するというのを徹底する。

// .prettierrc.jsmodule.exports = {
singleQuote: true,
};

インデント、セミコロンなどはデフォルト値を使用している。 prettierは設定項目が多くない(20項目)ので、デフォルトの値を使うルール含め全部書いてしまった方がわかりやすいかもしれないと思った。
ただ、アップデートで項目が増えた場合などに対応しないとわかりにくくなるのでやめた。prettierのデフォルト異なる設定が多い場合はその方がいいかもしれない。

1, 2で何が実行されるかというと

1で行われること

1を行う場合は prettier-eslint を使用して行うことになる。流れとしては、prettierでフォーマット→eslint --fix を実行する。

2で行われること

  • eslint-config-prettier でeslintとprettierでぶつかる設定を解消する。
  • eslint-plugin-prettier でeslintが行うフォーマットに、prettierのルールを採用させる。

Prettierのドキュメントに書いてあった。
eslint-config-prettier の挙動を確かめようと、ESLintでシングルクオテーション、Prettierでダブルクオテーションにすると、うまくいかない。
最終的にPrettierで指定した様にフォーマットされ、linterルールはESLintに従っている。eslint-config-prettier を導入しても、rulesに書いたことがlintルールに優先されてしまう模様。
そのため、フォーマットに関するruleは .eslintrc.js に一切書かない方がいい。

// .eslintrc.js...rules: {
'no-unused-vars':
'warn',
quotes: ["error", "double"],
},
// .prettierrc.jsmodule.exports = {
singleQuote: true,
};

.eslintIgnoreと.eslintrc.jsの設定

webpack, babel, eslintなどの設定ファイルも監視し、htmlファイルのエラーを除外するために.eslintIgnoreを下記の様に設定する

// .eslintIgnore*.html
dist/
# ドットで始まるファイルも監視する。
!.*.js

htmlファイルとdistディレクトリは監視の対象外とする。また、nodemodulesはデフォルトで監視の対象外となっている。

!.*.js で、ドットから始まるjsファイルを監視の対象外から外し、監視の対象とする。

これで必要十分なファイルのみ監視するようになった。

// .eslintrc.jsmodule.exports = {
env: {
browser: true,
es6: true,
node: true,
},
extends: ['eslint:recommended', 'plugin:prettier/recommended'],
globals: {
Atomics: 'readonly',
SharedArrayBuffer: 'readonly',
},
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
},
rules: {
// フォーマットの設定はここでは行わない。全て.prettierrc.jsで行う。
'no-unused-vars': 'warn',
},
};

nodeをtrueとすることで、コンフィグ系のファイルで記述していた module.exports などの記載をエラーではないとみなすようにした。また、dotEnvで使用している process も許可された。

どこかのディレクトリの配下(この場合はsrc)ではnodeを許可したくないのであれば、src直下に .eslintrc.js を設置し、下記の様にすればその設定が適用される。

// src/.eslintrc.jsmodule.exports = {
root: true,
env: {
browser: true,
es6: true,
},
extends: ['eslint:recommended', 'plugin:prettier/recommended'],
globals: {
Atomics: 'readonly',
SharedArrayBuffer: 'readonly',
process: 'readonly,
},
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
},
rules: {
// フォーマットの設定はここでは行わない。全て.prettierrc.jsで行う。
'no-unused-vars': 'warn',
},
};

rootをtrueとすることで、プロジェクトディレクトリ直下にある .eslintrc.js の設定は適用されなくなり、このファイルの設定のみを適用するようになる。

また、 process がエラーになるので、globals に追加した。

厳密にやりたい場合はこちらが望ましいかもしれないが、ディレクトリ毎にeslintの設定を変えているプロジェクトを見つけられなかったので、やらなかった。

vscodeでセーブをする度にprettier, eslintを実行する設定

これを行うことでセーブをするたびに自動でフォーマットが走るようになる。細かいことを気にせず好きにコードを書いても、勝手に修正されていくので、フォーマットエラーは基本的に発生しなくなる。そのためフォーマットに関する違反は error で問題ない。lintの違反のみ warnerror を区別すればいい。

まずはvscodeで下記の拡張をインストール

設定方法は、プロジェクトの設定を下記の様にすればいい。vscodeの設定を変更して、 setting.jsonをgitで管理して共有する様にしてしまった方がトラブルが少ないと思う。

// .vscode/setting.json{
"git.ignoreLimitWarning": true,
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[javascript]": {
"editor.formatOnSave": false
},
"[css]": {
"editor.formatOnSave": false
},
"[scss]": {
"editor.formatOnSave": false
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.fixAll.stylelint": true
},

"liveServer.settings.root": "/dist"
}

ここの設定はややこしく各ドキュメントを読む必要があった。

ESLintのウェブサイトからはこれらの統合についてのドキュメントは見つからなかった。

上記の設定について簡単に解説

まずはprettier-vscodeの説明にある通り、linterのフォーマット機能をオフにするか、linter経由でprettierを実行させるかを決める。

結論は

linterがprettierの設定でフォーマットする機能に関しては、formatOnSaveをオフ、それ以外の拡張子はしているをオン。だが、formatOnSaveを一括でオンにしても問題ない。

とした。

formatOnSave をtrueにするとlinterのフォーマット機能をオフにし、 formatOnSave をfalseにするとlinter経由でprettierを実行させる。後者の場合はvscodeのprettier拡張を使用しないことになる。

  • ESLint、style-lintに関してはどちらでも同じ。ESLintのフォーマット設定はprettierの設定を採用するため、eslintでフォーマットを行なっても、prettierでフォーマットを行なっても同じ結果になる。
  • 後者を一括で採用すると、ESLint, stylelint以外の .json, .md などの拡張子でオートフォーマットが効かなくなってしまう。

linterを用意していない拡張子でもフォーマットを効かせたいため、 formatOnSave はtrueにする。これだけでもいいのだが、コマンドでeslintを実行してフォーマットする時と、onSaveでフォーマットをする時でprettierが行うかeslintが行うかが下記の様に異なってしまう。

  • コマンドでフォーマット→eslintがフォーマット
  • onSaveでフォーマット→prettierがフォーマット

結果としては同じになるのだが、合わせておいた方が良さそうなので、linterを設定している拡張子に関しては個別に formatOnSave をfalseにし、それぞれのlinterにフォーマットを実行してもらう様にした。

いずれにしても eslintrc.js.prettierrc.js で矛盾するフォーマットの設定を行わない。そのために、 eslintrc.js ではフォーマットに関するruleを設定しないのが重要である。

setting.jsonを解説

各設定項目を簡単に解説すると

  • editor.formatOnSave は名前の通り。言語毎に指定できる。一括でtrueにし、特定の拡張子のみはfalseにしている。これによりサポートされている全ての拡張子でセーブ時にフォーマットが行われる。
  • editor.defaultFormatter も名前の通り、フォーマッターは何を使用するか。ここではprettierを指定している。
  • editor.codeActionsOnSave linterを使用してフォーマットをするものはオンにする。

また、eslint.autoFixOnSave の設定は、使用しないとのこと

まとめ

  • まずはprettierのフォーマット設定を使用して、ESlint, stylelintがフォーマットをかける設定をする。
  • linterではフォーマットの設定を指定しない。フォーマットの設定はprettierのみで行う。
  • vscodeのonSaveフォーマットでは、linterがフォーマットをするものはlinterに、それ以外はprettierにフォーマットさせる。

【感想】

とにかくややこしかった部分が理解できてすっきり。

--

--

Tatsuya Asami
Tatsuya Asami

Written by Tatsuya Asami

Front end engineer. React, TypeScript, Three.js

No responses yet