AstroプロジェクトへのESLint Flat Config導入例 (TypeScript, import, jsx-a11y)

[Astro]のプロジェクトに[ESLint]のFlat Configを導入する例です。サードパーティライブラリの[eslint-plugin-astro]を使用します。

eslint-plugin-astro
<https://ota-meshi.github.io/eslint-plugin-astro/>

## ライブラリ

```txt
- "@eslint/js": "^9.16.0"
- "@typescript-eslint/parser": "^8.17.0"
- "astro-eslint-parser": "^1.1.0"
- "eslint": "^9.16.0"
- "eslint-plugin-astro": "^1.3.1"
- "globals": "^15.13.0"
- "typescript-eslint": "^8.17.0"

# optional
- "eslint-config-prettier": "^9.1.0"
- "eslint-import-resolver-typescript": "^3.7.0"
- "eslint-plugin-import": "^2.31.0"
- "eslint-plugin-jsx-a11y": "^6.10.2"
```

この例では[eslint-config-airbnb-base]および[eslint-config-airbnb-typescript]からの移行を念頭に置いているため、[eslint-plugin-import]と[eslint-plugin-jsx-a11y]を導入していますが、これらの設定はお好みに合わせて任意で設定してください。

## 設定ファイル (`eslint.config.mjs`)

ESLint設定ファイルは2024年12月現在、`js` `cjs` `mjs` がデフォルトでサポートされています。TypeScriptでの記述(`ts` `mts` `cts`)は[追加設定を行えば可能](https://eslint.org/docs/latest/use/configure/configuration-files#typescript-configuration-files)ですが、使用するライブラリが型定義ファイルを持っているとは限らないので、現状`mjs`が無難な選択だと思われます。

```js:eslint.config.mjs
import globals from "globals";
import pluginJs from "@eslint/js";
import tseslint from "typescript-eslint";
import importPlugin from "eslint-plugin-import";
import jsxA11yPlugin from "eslint-plugin-jsx-a11y";
import eslintPluginAstro from "eslint-plugin-astro";
import astroParser from "astro-eslint-parser";
import typescriptEslintParser from "@typescript-eslint/parser";
import eslintConfigPrettier from "eslint-config-prettier";

/** @type {import("eslint").Linter.Config[]} */
export default [
  pluginJs.configs.recommended,

  /* optional */
  importPlugin.flatConfigs.recommended,

  ...tseslint.configs.recommended,

  /* optional */
  {
    plugins: {
      "jsx-a11y": jsxA11yPlugin,
    },
  },
  ...eslintPluginAstro.configs["jsx-a11y-recommended"],
  /**
   * jsx-a11yを使わない場合は以下の設定でok
   * ...eslintPluginAstro.configs.recommended,
   */

  {
    languageOptions: {
      ecmaVersion: 2022,
      sourceType: "module",
      globals: { ...globals.browser, ...globals.node },
    },
  },

  /* optional */
  {
    settings: {
      "import/resolver": {
        typescript: {},
      },
    },
  },

  {
    files: ["*.astro"],
    languageOptions: {
      parser: astroParser,
      parserOptions: {
        parser: typescriptEslintParser,
        extraFileExtensions: [".astro"],
      },
    },
  },

  /* optional */
  eslintConfigPrettier,
];
```

### Astro + TypeScript

基本的に[eslint-plugin-astro]のドキュメント通りに設定すればいいのですが、Astroファイル内のTypeScriptが解析されない事態が発生してしまいました。以下の記述を配列に加えることで、Astroファイル内のTSコードを読み込めるようになりました。

```js
import astroParser from "astro-eslint-parser";
import typescriptEslintParser from "@typescript-eslint/parser";

export default [
  // ...,
  {
    files: ["*.astro"],
    languageOptions: {
      parser: astroParser,
      parserOptions: {
        parser: typescriptEslintParser,
        extraFileExtensions: [".astro"],
      },
    },
  },
  // ...,
]
```

### jsx-a11y

[eslint-plugin-astro]は別途[eslint-plugin-jsx-a11y]をインストールすることで、Astroコンポーネントのアクセサビリティルール検出の設定を有効にすることができます。`jsx-a11y`プラグインを有効にし、通常の`recommended`に替えて`jsx-a11y-recommended`を記述します。より厳格なルールを適用したい場合は`jsx-a11y-strict`が選択可能です。

```js
import jsxA11yPlugin from "eslint-plugin-jsx-a11y";
import eslintPluginAstro from "eslint-plugin-astro";

export default [
  // ...
  {
    plugins: {
      "jsx-a11y": jsxA11y,
    },
  },
  ...eslintPluginAstro.configs["jsx-a11y-recommended"],
  // ...
]
```

### その他

#### eslint-import-resolver-typescript

[eslint-import-resolver-typescript]はTSConfigの`paths`オプションをESLintで解析できるようにするライブラリです。下記の設定を書くことで有効になります。

```js
export default [
  // ...,
  {
    settings: {
      "import/resolver": {
        typescript: {},
      },
    },
  },
  // ...,
];
```

#### eslint-config-prettier

[eslint-config-prettier]は最後に記述します。この設定ファイルは、[Prettier]と競合するESLintのルールをオフにするものであり、Prettierの設定に違反している箇所を検出するわけではありません。Prettierの設定に違反している箇所を検出する場合は別途[eslint-plugin-prettier]を使用します。

以上、AstroプロジェクトにESLintのFlat Configを導入する一例でした。

## リンク

ESLint
<https://eslint.org/>

eslint-plugin-astro
<https://ota-meshi.github.io/eslint-plugin-astro/>

[Astro]: https://astro.build/

[ESLint]: https://eslint.org/
[typescript-eslint]: https://typescript-eslint.io/
[eslint-config-prettier]: https://github.com/prettier/eslint-config-prettier
[eslint-plugin-import]: https://github.com/import-js/eslint-plugin-import
[eslint-import-resolver-typescript]: https://github.com/import-js/eslint-import-resolver-typescript
[eslint-plugin-astro]: https://ota-meshi.github.io/eslint-plugin-astro/
[eslint-plugin-jsx-a11y]: https://github.com/jsx-eslint/eslint-plugin-jsx-a11y
[eslint-config-airbnb-base]: https://www.npmjs.com/package/eslint-config-airbnb-base
[eslint-config-airbnb-typescript]: https://github.com/iamturns/eslint-config-airbnb-typescript

[Prettier]: https://prettier.io/
[eslint-plugin-prettier]: https://github.com/prettier/eslint-plugin-prettier