20251102

ESLint

https://eslint.org/

JavaScript(+ TypeScript)用の静的解析ツール。基本はJavaScript専用らしいがプラグインで拡張できるため、TypeScript用のプラグインを入れればTypeScriptにも使用できる。JSXについても同様。

設定ファイルは eslint.config.mjs に記述する。.js.mjs も使用可能。( .ts .mts .cts も使用可能だが実行環境がNode.jsの場合は追加の設定が必要).js を使用する場合、 package.json の設定( type )に応じてESM形式で読み込むかCommonJS形式で読み込むかが変わる。従来は .eslintrc を使用していたが非推奨となっている。

ESLintはルールベースのリントを行う。使用するルールを設定ファイルに追加し、各ルールに対して、off、warn、errorのいずれかを設定する。

設定オブジェクト

eslint.config.mjs で設定する内容について。設定はオブジェクト単位で行う。

どのファイルに対して何のルールを適用するか、の設定。

  • name :設定名。エラーメッセージなどに表示される?よくわからず。多分設定オブジェクトを共有する際に使用される。
  • basePath :設定を適用するサブディレクトリのパス。
  • files :設定を適用するファイル。
  • ignoresfiles で指定しているもののうち、設定を適用しないファイル。
  • extends :他の設定オブジェクト。設定の引き継ぎたい場合に使用する。
  • languageOptions :JavaScriptファイルに関しての細かい指定
    • ecmaVersion :サポートするECMAScriptバージョン。
    • sourceType :ソースコードのタイプ。 modulecommonjs など。
    • globals :リント時にグローバルオブジェクトとして追加する必要のあるオブジェクト。
    • parser :パーサーの切り替え? parse() または parseForESLint() を持つオブジェクト。
    • parserOptionsparse() または parseForESLint() に渡す追加のオプション。
  • linterOptions :リントプロセス関連の設定。
    • noInlineConfig :インラインコンフィグを許可するかどうか。
    • reportUnusedDisableDirectives :使われていないディレクティブを警告するかどうか
    • reportUnusedInlineConfigs :使われていないインラインコンフィグを警告するかどうか
  • processor :プロセッサーの切り替え? preprocess() または postprocess() を持つオブジェクト。
  • plugins :読み込むプラグイン。
  • rules :適用するルール。
  • settings :ルールから参照する情報。

defineConfig() に設定オブジェクトを配列で渡すことで、複数の設定オブジェクトをいい感じにまとめてくれる?

ESLintはViteやNext.jsのテンプレートに標準搭載されている。どちらも npm run lint で実行できる。

Viteの方は既存のルールセットを組み立てているのに対し、Next.jsでは独自にルールセットをまとめたプラグイン経由で使用している。

// Vite(TypeScript + React)で自動生成される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'
import { defineConfig, globalIgnores } from 'eslint/config'

export default defineConfig([
  globalIgnores(['dist']),
  {
    files: ['**/*.{ts,tsx}'],
    extends: [
      js.configs.recommended,
      tseslint.configs.recommended,
      reactHooks.configs['recommended-latest'],
      reactRefresh.configs.vite,
    ],
    languageOptions: {
      ecmaVersion: 2020,
      globals: globals.browser,
    },
  },
])
  • @eslint/js
    • JavaScript関連の設定
  • eslint-plugin-react-hooks
    • Reactのフック関連の設定
  • eslint-plugin-react-refresh
    • React Refresh(HMR)関連の設定
  • typescript-eslint
    • TypeScript関連の設定
// Next.jsで自動生成されるeslint.config.mjs

import { defineConfig, globalIgnores } from "eslint/config";
import nextVitals from "eslint-config-next/core-web-vitals";
import nextTs from "eslint-config-next/typescript";

const eslintConfig = defineConfig([
  ...nextVitals,
  ...nextTs,
  // Override default ignores of eslint-config-next.
  globalIgnores([
    // Default ignores of eslint-config-next:
    ".next/**",
    "out/**",
    "build/**",
    "next-env.d.ts",
  ]),
]);

export default eslintConfig;
  • eslint-config-next/core-web-vitals
    • React関連の設定 + Next.js関連の設定?
  • eslint-config-next/typescript
    • TypeScript関連の設定 + Next.js関連の設定?

エディタ設定

ESLintを使う場合はエディタ側にESLint用のプラグインを入れるのが推奨。自動でリントを走らせ、エディタ上にリントエラーを表示してくれる。

書式フォーマットルール

https://eslint.org/blog/2023/10/deprecating-formatting-rules/

ESLint8.53から書式のフォーマットに関するルール(以下例)については非推奨になった。

  • インデントサイズ
  • ダブルクォートかシングルクォートか
  • セミコロンの有無

これらの検出、修正は以下のようなフォーマッターに任せることを推奨している。

  • Prettier
  • Biome

インラインコンフィグ

全体のルールを無視して許容したい場合はコメントで指定できる。

/* eslint no-unused-vars: "off" */

function hello() { // 使ってないけどエラー抑制
  console.log("hello");
}

function goodbye() { // 使ってないけどエラー抑制
  console.log("hello");
}

/* eslint *** */ という書き方をするとファイル全体に適用される。

ファイル内の一部分だけルールを無視したい場合は /* eslint-disable *** *//* eslint-enable *** */ で囲う。

/* eslint-disable no-unused-vars */
function hello() { // 使ってないけどエラー抑制
  console.log("hello");
}
/* eslint-enable no-unused-vars */

function goodbye() { // 使ってないのでエラー
  console.log("goodbye");
}

対象が一行だけの場合は /* eslint-disable-next-line *** */ でもいい。

/* eslint-disable-next-line no-unused-vars */
function hello() { // 使ってないけどエラー抑制
  console.log("hello");
}

function goodbye() { // 使ってないのでエラー
  console.log("goodbye");
}

/* eslint-disable-line *** */ で「その行」を指定することも可能。

function hello() { /* eslint-disable-line no-unused-vars */ // 使ってないけどエラー抑制
  console.log("hello");
}

function goodbye() { // 使ってないのでエラー
  console.log("goodbye");
}