ESLint + typescript-eslint + Astroの理解を深める
設定ファイル
今までESLintを雰囲気で使っていたので、ある程度の理解を深めた上で設定ファイルを再考してみました。
現時点での結論としてはこんな感じ。
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のコードですね)。
推奨ルールをそのまま使い、特にカスタマイズはしていません。
ひとり開発が多く、特にこだわりもないので、基本的なルールだけは押さえておこうぐらいの気持ちです。
ファイルの種類ごとに設定を記述する
以下の記事がとても参考になりました。
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
のエラーが発生していることが確認できると思います。
そんなわけで、冒頭に紹介した通り、ファイルの種類ごとに設定を記述することにしました。
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
を使うことにしました。