🔍
ESLint設定まとめ:基本設定からルール設定の進め方まで
ESLintの基本設定とルール設定の進め方メモ
設定項目
ESLintの設定ファイルには、主に次の4つの項目が含まれる
- グローバル変数: 使用するECMAScriptのバージョンやブラウザ・Node.jsなどの環境を指定
- 構文解析エンジン: コードの構文解析エンジンを指定
- 解析対象のファイル: 解析対象のファイルを指定
- ルール: コードの品質やスタイルを揃えるためのルールを設定
グローバル変数
- 使用するECMAScriptのバージョンやブラウザ・Node.jsなどの環境を指定できる
→ 対応するグローバル変数をESLintに認識させることができる - 設定例:
"env": {
"browser": true, // `window`, `document` などを使用可能にする
"node": true, // `require`, `process` などを使用可能にする
"es2022": true // ES2022 の構文を許可
}
例えば、"browser": true
を指定しないと、以下のようなコードでエラーが発生する
console.log(window.location.href);
// ESLint エラー: 'window' is not defined. (no-undef)
構文解析エンジン
- コードの構文解析エンジンを指定できる
- デフォルトはespree
- TypeScriptを使う場合は@typescript-eslint/parserなどに変更する
- 設定例:
"parser": "@typescript-eslint/parser"
- 例えば、
"parser": "@typescript-eslint/parser"
を指定しないと、以下のようなコードでエラーが発生する
const message: string = "Hello";
// ESLint エラー: Parsing error: Unexpected token ':'
解析対象のファイル
- 解析対象のファイルを指定できる
- 設定例
"files": ['**/*.{ts,tsx}'],
→ .ts / .tsx ファイルを解析対象に含める
ルール
- コードの品質やスタイルを揃えるためのルールを設定できる
- 300以上のルールがある
- ルールは
"off" | "warn" | "error"
のレベルで設定できる
設定値 | 挙動 |
---|---|
"off" |
ルールを適用しない(チェックしない) |
"warn" |
ルールに違反すると黄色の警告(VSCodeで波線、コンソールに警告) |
"error" |
ルールに違反すると赤いエラー(VSCodeで波線、コンソールにエラー、CIでは失敗) |
- 設定例
"rules": {
"semi": ["error", "always"], // セミコロンを常に要求
"quotes": ["error", "double"] // 文字列はダブルクォートを使用
}
- 例えば、TypeScript ファイルを解析対象に含めないと、以下のようなコードでエラーが発生する
const message: string = "Hello";
// ESLint エラー: Parsing error: Unexpected token ':'
設定方法
- eslint.config.js(Flat Config)はv8で導入され、v9で .eslintrc のサポート終了が予定されているため、移行が推奨
- 新しいプロジェクトでは eslint.config.js を採用するのが良さそう(Next.jsではv15からFlat Configに対応)
- Flat Configにするメリット
-
Lintを実行する前に設定ミスを発見できる
- .eslintrc では、pluginsやextendsを文字列で指定するため、Lint実行時にしかエラーが分からない
module.exports = { extends: ["plugin:import/recommended"], plugins: ["import"], // Failed to load plugin 'import': Cannot find module 'eslint-plugin-import' };
- Flat Configではimportを使うため、エディタや型チェックで即エラーが分かる
import importPlugin from "eslint-plugin-import"; // Error: Cannot find module 'eslint-plugin-import' export default [ { plugins: { import: importPlugin, }, ...importPlugin.configs.recommended, }, ];
-
グローバル変数の設定方法
-
eslint.config.jsの場合
- languageOptions.globals
を使用して、環境ごとのグローバル変数を利用可能にする
- languageOptions.globals
-
例えば、ブラウザ向けのコードを書く場合、globals.browserを設定
eslint.config.js
import globals from "globals";
export default [
{
languageOptions: {
globals: {
...globals.browser, // `window`, `document` などを使用可能にする
...globals.es2022 // ES2022 のグローバル変数を許可
}
}
}
];
.eslintrc.jsの場合
module.exports = {
env: {
browser: true, // `window`, `document` などを使用可能にする
es2022: true // ES2022 の構文を許可
}
};
構文解析エンジンの設定方法
- eslint.config.jsの場合
- languageOptions.parser
- languageOptions.parserOptions
を使用して、適切な構文解析エンジンを設定
例えば、TypeScriptを使用する場合は@typescript-eslint/parser
を設定
eslint.config.js
import tsParser from "@typescript-eslint/parser";
export default [
{
languageOptions: {
parser: tsParser,
parserOptions: {
project: "./tsconfig.json",
},
},
},
];
.eslintrc.js の場合
module.exports = {
parser: "@typescript-eslint/parser",
parserOptions: {
project: "./tsconfig.json",
},
};
ちなみに構文解析エンジンが必要になるケース
標準のJavaScript構文解析エンジンで対応できない場合に指定
- .ts, .tsx (TypeScript) → @typescript-eslint/parser
- .vue (Vue) → vue-eslint-parser
- .svelte (Svelte) → svelte-eslint-parser
解析対象のファイルの設定方法
- eslint.config.jsの場合
- files
- ignores
を使用して、解析対象のファイルを設定
eslint.config.js
export default [
{
files: ['**/*.{ts,tsx}'],
ignores: ["dist"], // `node_modules`はデフォルトで除外
},
];
.eslintrc.js の場合
module.exports = {
// `files` に相当する項目はない、解析対象のファイルを設定するには、コマンドラインで `--ext` オプションを使用する
// 例: `eslint --fix --ext .jsx,.js,.tsx,.ts .`
ignorePatterns: ["dist"], // `node_modules`はデフォルトで除外
};
ルールの設定方法
- eslint.config.jsの場合
- rules
- extends
- plugins
を使用して、ルールを設定
- extendsは後ろに書いたものが前の設定を上書きし、最終的なルールの適用はrulesが優先される
ルールの設定パターン
ESLintの標準ルールを変更する場合
ESLintに最初から含まれているルールの設定を変更する方法
- 一部変更する場合
-
rules
に設定
-
eslint.config.js
export default {
rules: {
"no-console": "error",
},
};
.eslintrc.js の場合
module.exports = {
rules: {
"no-console": "error",
},
};
- まとめて変更する場合
- Sharable Config(共有設定)を利用し、多くのルールをまとめて変更
eslint.config.js
import standard from "@eslint-config-standard";
export default [
standard,
];
.eslintrc.js の場合
module.exports = {
extends: "standard",
};
ESLintの標準ルールにないルールを追加する場合
ESLintに含まれていないルールを追加する方法、プラグインを導入して適用する
- 一部を変える場合
- プラグインを追加し、そのプラグイン内の特定のルールのみ適用
eslint.config.js
import unusedImports from 'eslint-plugin-unused-imports';
export default [
{
plugins: {
'unused-imports': unusedImports,
},
rules: {
'unused-imports/no-unused-imports': 'error',
},
},
];
.eslintrc.jsの場合
module.exports = {
plugins: ["import"],
rules: {
"import/no-unresolved": "error",
},
};
- まとめて変更する場合
- プラグインを追加し、そのプラグイン内の推奨ルールをまとめて適用
eslint.config.js
import reactHooks from 'eslint-plugin-react-hooks'
export default tseslint.config(
{
plugins: {
'react-hooks': reactHooks,
},
rules: {
...reactHooks.configs.recommended.rules,
},
},
)
or
eslint.config.js
import importPlugin from 'eslint-plugin-import';
export default [
importPlugin.flatConfigs.recommended,
];
.eslintrc.js の場合
module.exports = {
plugins: ["react-hooks", "import"],
extends: ["plugin:react-hooks/recommended", "plugin:import/recommended"],
};
Sharable Configやプラグイン適用時の注意点
- eslint-plugin-importのように、プラグインが内部でpluginsを追加しているケースもあるため、明示的にpluginsに記述しなくても適用されることがある
https://github.com/import-js/eslint-plugin-import/blob/4f145a2c64af4931f4bf3ae951c8b719b544718f/src/index.js#L86 - Sharable Configやプラグインの中には、他のプラグインをいくつかまとめて含んでいるものもある
- 例えば、eslint-config-next(https://nextjs.org/docs/app/api-reference/config/eslint) は
- eslint-plugin-next
- eslint-plugin-react
- eslint-plugin-react-hooks
- eslint-plugin-jsx-a11y
を含んでいる
→ ESLintの設定をシンプルに保つため、フレームワークやプラグインのアップデートを定期的に確認する
- 新しいルールが追加されると、以前手動で設定していたルールが不要になることがあるため、その際は設定を見直したほうがよさそう
- 例えば、eslint-config-next(https://nextjs.org/docs/app/api-reference/config/eslint) は
ルール設定の進め方(個人開発)
-
使っている技術を整理し、各技術に応じたプラグインをawesome-eslintを参考に選定
- 例
- React → eslint-plugin-react
- TypeScript → @typescript-eslint/eslint-plugin
- Tailwind CSS → eslint-plugin-tailwindcss
- Jest → eslint-plugin-jest
- 例
-
その他良さそうなプラグインも選定
- 例
- import構文整理 → eslint-plugin-import, eslint-plugin-unused-imports
- アクセシビリティ関連 → eslint-plugin-jsx-a11y
- Prettier との競合を防ぐ → eslint-config-prettier(ESLint自体からフォーマットのルールは削除されたが、他のプラグインのフォーマット関連のルールを抑制するために必要)
- 例
-
既存のプラグインと機能が重複しないか確認し、最適な組み合わせを選定
-
プラグインの推奨設定や個別ルールの設定方法を確認
例: Vite + TypeScript + React の場合
- create-viteでテンプレートを作ると、次のeslint.config.jsが自動で作成される
eslint.config.js
eslint.config.js
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
export default tseslint.config(
{
extends: [js.configs.recommended, ...tseslint.configs.recommended],
files: ['**/*.{ts,tsx,js,jsx}'],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
plugins: {
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
},
rules: {
...reactHooks.configs.recommended.rules,
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
},
{ ignores: ['dist'] },
)
tseslint.configについて
-
使っている技術を整理し、各技術に応じたプラグイン、その他良さそうなプラグインも適宜選定
技術 プラグイン React eslint-plugin-react TypeScript @typescript-eslint/eslint-plugin import 構文整理 eslint-plugin-import, eslint-plugin-unused-imports アクセシビリティ eslint-plugin-jsx-a11y Prettier との競合防止 eslint-config-prettier -
プラグインの重複を確認し最適な組み合わせを選定
プラグイン 重複状況(@eslint/js, eslint-plugin-react-hooks, typescript-eslintとのルール重複) eslint-plugin-react 重複なし @typescript-eslint/eslint-plugin typescript-eslint
に含まれるeslint-plugin-import 重複なし eslint-plugin-unused-imports 重複なし eslint-plugin-jsx-a11y 重複なし eslint-config-prettier 重複なし -
推奨設定の適用または個別ルールの設定の適用
- eslint-plugin-react
- eslint-plugin-import
- eslint-plugin-unused-imports
- eslint-plugin-jsx-a11y
- eslint-config-prettier
を適用する
サンプルコード
参考資料
Discussion