前言#
これは ESLint と他の関連ツールの優劣を比較する記事ではなく、私がコードチェックとフォーマットに ESLint を選んだ理由を紹介するものです。他のツールについて言及せざるを得ない場合もありますが、私は人気のあるツールが存在するのは、それぞれに特徴と利点があるからだと思います。ユーザーとして、私たちは自分のニーズや好みに基づいて適切なツールを選べばよいのです。ツールに問題がある場合は、フィードバックや貢献を通じて改善を手助けできます。
私が注目する ESLint の利点#
より柔軟なフォーマット#
なぜPrettierやdprintのようなフォーマッティングツールを使用しないのかについて、Anthony Fu のWhy I don't use Prettierの記事が十分に明確に述べています。ここで、私の考えを少し補足します。
printWidth
を設定しても、Prettier にいつ改行したいかを伝えることはできません。printWidth
の値を増やして、改行すべきでない長い文字列変数を回避しようとすると、改行されることを期待している多引数関数の引数が正しく改行されない可能性があります。// prettier-ignore
の問題は// @ts-ignore
と同様で、ツールにここで改行しないように伝えることには成功しますが、同時にここで適用できた他のフォーマットルールを失ってしまいます。
Prettier の哲学は、ユーザーがフォーマットの設定オプションを考慮する必要がなく、コードを安心して美しくしてもらうことですが、実際には既存の設定オプションが Prettier が現在の js コミュニティで最も人気のあるフォーマッティングツールの一つになった理由の一つかもしれません。想像してみてください、tab
とspace
のどちらでインデントするかを制御できないフォーマッティングツールを使用しますか?tab
とspace
の争いが基本的に五分五分の状況を考えると、このオプションがなければ、Prettier は少なくとも半分のユーザーを失うことになります。
さらに、あまり議論のないオプションについては、Prettier の頑固さがユーザーにとっていくつかの困惑をもたらすことがあります。たとえば、Prettier はファイルの末尾に空行を強制的に保持しますが、これは設定できないものです。この動作は大多数の人に支持され、git などのツールに有利ですが、耐えられない人にとっては、いくつかのハック手段を探すか、Prettier の代わりに他のツールを探さなければなりません。
はい、私たちは dprint のような他のフォーマッティングツールを選ぶことができますが、それはパフォーマンスが優れていて、より多くの設定オプションを提供しています。しかし、それでも、コードがいつ改行されるべきかという問題を解決していません。これはバグではなく、それらの作業モード自体によって決まっています。さらに、dprint はより多くの設定オプションを持っていますが、すべての人のニーズを満たすことは決してできません。ESLint の世界では、既存のルールのオプションを設定したり、プラグインを書いたりすることで、自分のニーズを簡単に実現できます。
ESLint のスタイリスティックな既存のルールが jsx 内の複数の引数間のスペースを処理していないことに気づいたとき、私は現在のコードを typescript-eslint のplaygroundに置き、右側の ESTree で表示されるデータ構造に基づいてプラグインを書くことで、自分のニーズを実現できます。
拡張性#
パフォーマンスの良い言語を使用して元々js で書かれたツールを再構築することで、より良いパフォーマンスを得ることができます。しかし、これは通常代償を伴います。Rust で書かれた lint ツールは一般的にルールを簡単にカスタマイズできないため、ESLint コミュニティで非常に人気のあるルールのみが移植されることになります。これは、私たちが公式にリリースされた ESLint プラグイン、たとえば React Compiler のリリースに伴うeslint-plugin-react-compilerをすぐに利用できないことを意味します。また、ESLint コミュニティの中でニッチだけど非常に便利なプラグイン、たとえばESLint Plugin Commandも利用できません。
ルールの拡張に加えて、ESLint は lint の言語を拡張することもサポートしています。現在、Vue、JSON、YAML、Toml、Markdown、Astro、Svelte などの言語で ESLint を使用してコードチェックを簡単に行うことができます。しかし、ネイティブ言語で書かれた lint ツールは、通常、最も主流の言語を優先的にサポートすることしかできません。たとえば、Biome を使用している場合、Vue プロジェクトを書くときには一時的にそれを使用できず、ESLint に戻る必要があります。異なるプロジェクトで異なるツールを使用することによる不一致はあまり好きではありません。
優れたエコシステム#
このセクションでは、ESLint のプラグインエコシステムがどれほど豊富であるかを再度言及したくありません。私たちはESLint VSCodeプラグインについて話しましょう。私たちが毎日使用する保存時の自動修正機能に加えて、いくつかの他の便利な機能も提供しています。
ESLint を使用する際に、自動修正してほしいルールがいくつかありますが、保存時にすぐに修正されるわけではありません。たとえば、未使用の import を削除したり、let をすぐに const に変更したり(変数にすぐに再代入する可能性があります)することです。この場合、eslint.codeActionsOnSave.rules
を設定できます。
{
"eslint.codeActionsOnSave.rules": [
"!prefer-const",
"!unused-imports/no-unused-imports",
"*"
]
}
lint-staged
とsimple-git-hooks
を組み合わせることで、エディタ内で特定のルールを無視し、コミット前に自動修正を実現できます。
もう一つ非常に便利な設定はeslint.rules.customizations
です。前述のように、一部のルールの自動修正を無効にしましたが、エディタはそれをエラーとして表示し続けます。この設定を使用することで、これらのルールの重大度を下げたり、完全に無効にしたりできます。
{
"eslint.rules.customizations": [
{ "rule": "@stylistic/*", "severity": "off" },
{ "rule": "@stylistic/no-tabs", "severity": "default" },
{ "rule": "@stylistic/max-statements-per-line", "severity": "default" },
{ "rule": "antfu/consistent-list-newline", "severity": "off" },
{ "rule": "prefer-const", "severity": "off" },
{ "rule": "unused-imports/no-unused-imports", "severity": "off" },
{ "rule": "simple-import-sort/*", "severity": "off" }
]
}
この設定は、ESLint をコードフォーマッティングツールとして使用するのに非常に役立ちます。エディタ内で ESLint スタイリスティックのルールのエラー表示を直接無効にし、自動修正機能を保持できます。次のバージョンでは、すべての自動修正可能なルールの重大度を調整できるようになります。
タイプ認識の lint ルール#
Rust ベースの lint ツールは非常に速いですが、タイプ情報を使用して lint する能力はありません。Josh Goldberg はRust-Based JavaScript Linters: Fast, But No Typed Linting Right Nowで非常に詳細に説明しています。
oxlint は最近試みを行いましたが、これも JavaScript の速度に戻ったようです。
Biome はタイプ認識の linter を実装する準備を始めました。
私があまり気にしない ESLint の「欠点」#
パフォーマンス#
oxlint や biome などのツールのパフォーマンスが ESLint をはるかに上回ることを示すベンチマークが非常に多くあります。しかし、私の使用シーンから見ると、パフォーマンスの問題はそれほど重要ではないようです。
エディタ内でのリアルタイム lint と precommit 時の lint は、通常、少数のファイルをチェックするだけで済みます。完全な lint プロセスは CI に任せることができます。CI は私たちのローカル開発プロセスをブロックすることはなく、CI でエラーが発生したときに特定のファイルをローカルで lint すればよいのです。
私がエディタ内でパフォーマンスの問題が発生するのは、プロジェクトが徐々に大きくなり、タイプチェックに基づくルールを有効にすると、エディタの保存操作に明らかな遅延が生じる場合です。しかし、この時、タイプチェックに基づくルールを完全に妥協する必要はありません。ESLint Flat Config の柔軟性により、エディタ内で特定のルールを無効にすることができます。ターミナルや CI 環境では、依然として完全な lint を行うことができます。
私自身の ESLint Config は、以下のような設定を使用できます。
import defineConfig from "eslint-config-hyoban";
const isInEditor = !!(
(process.env.VSCODE_PID ||
process.env.VSCODE_CWD ||
process.env.JETBRAINS_IDE ||
process.env.VIM) &&
!process.env.CI
);
export default defineConfig({
typeChecked: isInEditor ? false : "essential",
});
あなたも tsslint を試してみることができます。これは TypeScript 言語サーバーとシームレスに統合された軽量チェックツールです。
非公式の推奨#
ESLint と typescript-eslint の公式は、コードフォーマットに関連するルールを廃止することを決定し、ESLint をフォーマットに使用することを推奨しないとし、Prettier などのフォーマッティングツールと組み合わせて使用することを推奨しています。しかし、実際にはこれは問題ではないと思います。これらのルールを廃止し、コミュニティに維持を移行することは実際には良いことです。私たちは今、ESLint Stylisticのような即使用可能なツールを持っており、非常に良いパフォーマンスを示しています。
設定が複雑で、アップグレードが面倒#
最近の ESLint 9.0 は、多くの人にとって ESLint のメジャーバージョンアップが非常に複雑だと感じさせました。主な問題は、新しい設定ファイル形式により、設定を再記述する必要があることや、API のブレイキングチェンジにより多くの使用しているプラグインが 9.0 で使用できなくなることです。
しかし、私はこれは一時的な問題だと思います。新しい設定ファイルは多くの有用な新しいツールや使用法をもたらし、利点が欠点を上回ります。ESLint Config Inspectorは、設定ファイルをより良く作成し、テストするのに役立ちます。また、プロジェクトにインストールされた依存関係に基づいて動的に設定を生成することもできます(react をインストールしたプロジェクトでのみ react hooks 関連のルールを有効にするなど)。
API のブレイキングチェンジによる問題も、さまざまな方法で解決できます。
- 上流のプラグインに PR を作成して ESLint v9 に適応させる。多くの場合、数行のコードを修正するだけで、ESLint v9 で新しい API を使用し、古い API を互換性のために保持できます。
- 一時的に ESLint v8 を使用し、プラグインが適応するのを待つ(依然として Flat Config を使用できます)。
- 公式が提供するESLint Compatibility Utilitiesを使用して、アップグレードを支援します。
结语#
再度強調したいのは、これは私の個人的な感想と見解であり、考慮が不十分な点があるかもしれません。あなたと交流することを歓迎し、あなたの見解を共有していただければと思います。
もし今 ESLint All In One を試してみたいのであれば、Anthony Fu の ESLint config から始めることを強くお勧めします。これは非常に多くの言語とフレームワークをサポートしており、その上で柔軟に設定を行うことができます。
もしあなたが主に TypeScript と React を書くのであれば、私の ESLint config を試してみることもお勧めします。私の設定ルールの哲学は、できるだけプラグインのプリセットルールを使用し、その上で自分の習慣に合わせて調整し、strict
とtypeChecked
オプションを提供して異なるレベルの調整を行うことです。