Open3

ESLint + typescript-eslint + Astroの理解を深める

Yuichiroh AraiYuichiroh Arai

設定ファイル

今までESLintを雰囲気で使っていたので、ある程度の理解を深めた上で設定ファイルを再考してみました。

現時点での結論としてはこんな感じ。

eslint.config.mjs
import eslint from "@eslint/js";
import eslintPluginAstro from "eslint-plugin-astro";
import { defineConfig } from "eslint/config";
import globals from "globals";
import tseslint from "typescript-eslint";

export default defineConfig([
  {
    files: ["**/*.{js,mjs}"],
    extends: [eslint.configs.recommended],
    languageOptions: {
      globals: {
        ...globals.browser,
        ...globals.node,
      },
    },
  },
  {
    files: ["**/*.ts"],
    extends: [eslint.configs.recommended, tseslint.configs.recommended],
  },
  {
    files: ["**/*.astro"],
    extends: [
      eslintPluginAstro.configs.recommended,
      tseslint.configs.recommended,
      eslintPluginAstro.configs.recommended,
    ],
  },
]);

AstroプロジェクトでTypeScriptをメインで使い、たまにJavaScriptのコードが含まれることを想定しています(この設定ファイル自体が.mjsでJavaScriptのコードですね)。

推奨ルールをそのまま使い、特にカスタマイズはしていません。
ひとり開発が多く、特にこだわりもないので、基本的なルールだけは押さえておこうぐらいの気持ちです。

Yuichiroh AraiYuichiroh Arai

ファイルの種類ごとに設定を記述する

以下の記事がとても参考になりました。
https://susisu.hatenablog.com/entry/2025/03/30/153957

typescript-eslintのドキュメントでは、以下の設定方法が紹介されています。

import eslint from '@eslint/js';
import { defineConfig } from 'eslint/config';
import tseslint from 'typescript-eslint';

export default defineConfig(
  eslint.configs.recommended,
  tseslint.configs.recommended,
);

ですが、これだとJavaScriptのファイルもTypeScriptとしてリントされてしまいます。

例えば、以下の単独のコードは未使用の変数が存在するのでエラーになります。

const x = 1;

このルールはESLintではno-unused-varsとして規定されています。
一方で、typescript-eslintでは@typescript-eslint/no-unused-varsとして再規定されていて、ESLintのno-unused-varsは無効化する必要があるとしています。

実際にJavaScriptのファイルに対してもtypescript-eslintが適用されてしまった場合、@typescript-eslint/no-unused-varsのエラーが発生していることが確認できると思います。

そんなわけで、冒頭に紹介した通り、ファイルの種類ごとに設定を記述することにしました。

Yuichiroh AraiYuichiroh Arai

JavaScriptファイルに対する設定解説

{
  files: ["**/*.{js,mjs}"],
  extends: [eslint.configs.recommended],
  languageOptions: {
    globals: {
      ...globals.browser,
      ...globals.node,
    },
  },
}

拡張子は.js(主にブラウザ向け) .mjs(主にNode.js向け)を対象にしています。

グローバル変数

ブラウザ/Node.jsそれぞれのグローバル変数を追加しています。

ESLintでは、このグローバル変数の設定がないと、console.logの記述などでno-undefのエラーが発生します。

typescript-eslintではno-undefが無効化されているのでこのエラーは発生しません。
恐らく、TypeScriptではグローバル変数は型定義によって解決されるべきで、リンタではなくコンパイラの領分なのだと思います。

そんなわけで、JavaScriptファイルにもtypescript-eslintが適用されている時は必要がなかった、グローバル変数の設定を追加しています。

eslint.configs.recommendedの中身

rules: {
  'constructor-super': 'error',
  ...
  'valid-typeof': 'error'
}

ルールが記述されているだけです。

なので、extendsを使わずに以下のように記述した方が、defineConfigでマージした結果がシンプルになります。

{
  files: ["**/*.{js,mjs}"],
  rules: eslint.configs.recommended.rules,
  languageOptions: {
    ...
  },
}

今回は一貫性を保つためにextendsを使うことにしました。