この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
すでにこちらの方の解説ブログもありますが、ESLint と Prettier を組み合わせる場合の推奨方法が変わりました。
Prettier と ESLint の組み合わせの公式推奨が変わり plugin が不要になった
本稿では リポジトリに適用してみて Before/After を具体的に見ていきます。
TL;DR
エディタが ESLint にも Prettier にも対応しているならば ESLint から eslint-plugin-prettier を除外し、ESLint と Prettier が個別に実行されるようにする。
コンテンツ
- 推奨がどう変わったか
- どこをどう変更すればよいか
- Intellij IDEA / WebStorm の場合、どの設定を変更すればよいか
推奨がどう変わったか
Prettier はもともと ESLint のプラグインとしても使うことができました。多くのエディタが eslint --fix
をサポートしていることから、長らく eslint --fix
のついでに整形も行うような形がとられていました。しかし、VSCode や JetBrains が Prettier を個別に実行できるようになり、
- ESLint のような静的解析ツールの自動修正機能
- コードフォーマッタである Prettier
これらを個別で実行するようにしてほしい、と変わったようです。Linterとの統合について述べている、こちらのドキュメントを見ます。
Integrating with Linters · Prettier
Prettier vs. Linters · Prettier
意訳すると以下のようなメッセージだと解釈しています。
- 静的解析ツールである ESLint と、コードフォーマッタである Prettier は本来分けて考えるべきもの
- ただ、Prettier が出たばかりのときは、エディタが Prettier に対応しておらず、ESLint のプラグインとしてフォーマットを実行できることには意味があった
- Prettier に対応しているエディタも増えてきた。以下のような理由もあるので Linterのプラグインとしてではなく、Prettier 単体で実行してほしい:
- 静的解析ツールのプラグインとしてフォーマッタを当てると、エディターに赤い波線がたくさん表示され、煩わしくなる
- Prettierを直接実行するよりも遅い
- 不整合が起きる可能性がある
どこをどう変更すればよいか
大きく、
eslint.rc.js
からeslint-plugin-prettier
を除去するpackage.json
のスクリプトでeslint --fix
相当のことをやっていた箇所でeslint --fix && prettier --write
に変更する
これらを変更します。
実際に分離した例
TypeScript のバリデータライブラリで試しました。差分のプルリクエストはこちらです。説明用のサンプルとして使います。
fix formatter by cm-wada-yusuke · Pull Request #6 · cm-madlabs/ts-validator
eslint.rc.js
から eslint-plugin-prettier
を除去する
.eslintrc.js
module.exports = {
env: {
node: true,
},
parser: '@typescript-eslint/parser',
plugins: ['node', '@typescript-eslint'],
parserOptions: {
sourceType: 'module',
},
rules: {
semi: 'off',
'@typescript-eslint/semi': ['error'],
// `export` functions may be listed first.
'@typescript-eslint/no-use-before-define': [
'error',
{ functions: true, classes: false, variables: true },
],
// To read environment variables.
'@typescript-eslint/no-non-null-assertion': 'off',
// Disable the eslint side because it conflicts with the prettier.
'@typescript-eslint/indent': 'off',
// Parameter functions return type is obvious and need not to be explicit.
'@typescript-eslint/explicit-function-return-type': [
'error',
{
allowExpressions: true,
allowTypedFunctionExpressions: true,
allowHigherOrderFunctions: true,
},
],
},
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended', // 消す
'prettier', // 追加する
],
};
これで eslint --fix
では prettier が走らないようになります。
'prettier' は必要?
必要だと思います。たいていの場合、 eslint-plugin-prettier
とは別に、ESLint で Prettier と競合するルールを無視するための eslint-config-prettier もインストールされているはずです。競合の回避は必要なので、 ESLintで有効にするため prettier
に書き換えます。これで、競合を回避するための設定だけが引き続き ESLint で利用できます。
package.json
を修正する
package.json
{
"name": "@cm-madlabs/ts-validator",
"version": "1.0.3",
"description": "true/false generic validator",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"author": "waddy",
"license": "MIT",
"private": false,
"publishConfig": {
"access": "public"
},
"keywords": [
"TypeScript",
"Validator"
],
"bugs": {
"url": "https://github.com/team-mad/ts-validator/issues"
},
"homepage": "https://github.com/team-mad/ts-validator#typescript-validator",
"scripts": {
"build": "tsc -p tsconfig.json",
"build:doc": "typedoc",
"test": "jest",
"test:coverage": "yarn jest --coverage",
"lint": "eslint './{lib,src,test}/**/*.{ts,tsx}'",
"lint-fix": "eslint --fix './{lib,src,test}/**/*.{ts,tsx}' && prettier --write './{lib,src,test}/**/*.{ts,tsx}'",
"lint-staged": "lint-staged",
"clean": "shx rm -rf ./dist && shx rm -rf './{src}/**/*.js' && shx rm -rf './{src}/**/*.d.ts'"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.ts": [
"yarn run lint-fix",
"yarn run lint",
"git add"
]
},
"dependencies": {
"luxon": "^1.25.0"
},
"devDependencies": {
"@types/luxon": "^1.25.0",
"@typescript-eslint/eslint-plugin": "^4.4.1",
"@typescript-eslint/parser": "^4.4.1",
"codecov": "^3.8.0",
"eslint": "^7.11.0",
"eslint-config-prettier": "^6.12.0",
"eslint-plugin-node": "^11.1.0",
"husky": "^4.3.0",
"jest": "^26.5.3",
"jest-coverage-badges": "^1.1.2",
"lint-staged": "^10.4.0",
"prettier": "^2.1.2",
"shx": "^0.3.2",
"ts-jest": "^26.4.1",
"ts-node": "^9.0.0",
"typedoc": "^0.19.2",
"typescript": "^4.0.3"
}
}
eslint --fix './{lib,src,test}/**/*.{ts,tsx}' && prettier --write './{lib,src,test}/**/*.{ts,tsx}'
のように、どちらも明示的に修正が走るようにします- dependencies から
eslint-plugin-prettier
を消します eslint-config-prettier
は消しません
yarn lint-fix
の結果は変えずに、ESLint と Prettier を分離できました。
Intgllij IDEA で prettier フォーマッタが走るようにする
最後はエディタの設定です。これまでは、Intellijで eslint --fix
相当の自動フォーマットを走らせれば Prettier も動作させることができました。
追加して、Prettier も走らせられるようにします。
これでフォーマット時に Prettier による整形も実行できます。完全に余談ですが私は「フォーマット」と「保存」は明確に分けて実行したいので保存時にフォーマットする設定は無効にしています。作業を中断する場合など、あえて文法エラーを残して保存しコンテキストを維持する…といった目的です。
まとめ
エディタでPrettierを実行できるようになり、ESLint と Prettier は個別に設定・適用することが推奨されています。本稿がどなたかの参考になれば幸いです。
ソースコード
fix formatter by cm-wada-yusuke · Pull Request #6 · cm-madlabs/ts-validator