Hyoban

Hyoban

Don’t do what you should do, do you want.
x
github
telegram
follow
email

なぜ ESLint なのか

前言#

これは ESLint と他の関連ツールの優劣を比較する記事ではなく、私がコードチェックとフォーマットに ESLint を選んだ理由を紹介するものです。他のツールについて言及せざるを得ないこともありますが、私は人気のあるツールが存在するのは、それぞれに特徴と利点があるからだと思います。ユーザーとしては、自分のニーズや好みに基づいて適切なツールを選べばよいのです。ツールに問題がある場合は、フィードバックや貢献を通じて改善を手助けできます。

私が重視する ESLint の利点#

より柔軟なフォーマット#

なぜPrettierdprintのようなフォーマットツールを使用しないのかについては、Anthony Fu のWhy I don't use Prettierの記事が十分に明確に述べています。ここでは、自分の考えを少し補足します。

printWidthを設定しても、Prettier にいつ改行したいかを伝えることはできません。printWidthの値を増やして、改行すべきでない長い文字列変数を回避しようとすると、期待していた多引数関数の引数が正しく改行されない可能性があります。// prettier-ignoreの問題は// @ts-ignoreと同様で、ツールにここで改行しないように伝えることには成功しますが、同時にここで適用できた他のフォーマットルールを失ってしまいます。

Prettier の哲学は、ユーザーがフォーマットの設定オプションを考慮する必要がなく、コードを安心して美しくしてもらうことですが、実際には既存の設定オプションが Prettier が現在の JS コミュニティで最も人気のあるフォーマットツールの一つになった理由の一つかもしれません。想像してみてください、tabspaceでインデントを制御できないフォーマットツールを使いますか?tabspaceの争いがほぼ五分五分の状況を考えると、このオプションがなければ、Prettier は少なくとも半分のユーザーを失うでしょう。

また、あまり議論のないオプションに関しては、Prettier の頑固さがユーザーにとっていくつかの困惑をもたらすことがあります。例えば、Prettier はファイルの末尾に空行を強制的に残すことがあり、これは設定できないものです。この動作は大多数の人に支持され、git などのツールに有利ですが、我慢できない人にとっては、いくつかのハック手段を探したり、Prettier の代わりに他のツールを探さざるを得ません。

はい、dprint のような他のフォーマットツールも選択肢としてありますが、パフォーマンスが優れていて、より多くの設定オプションを提供しています。しかし、同様に、それでもコードがいつ改行されるべきかの問題を解決していません。これはバグではなく、それらの作業モード自体によって決まっています。さらに、dprint の設定オプションが多くても、すべての人のニーズを満たすことは決してできません。ESLint の世界では、既存のルールのオプションを設定したり、プラグインを書くことで、自分のニーズを簡単に実現できます。

ESLint のスタイリスティックな既存のルールが jsx 内の複数の引数間のスペースを処理していないことに気づいたとき、私は現在のコードを typescript-eslint のplaygroundに置き、右側の ESTree が示すデータ構造に基づいてプラグインを書くことで、自分のニーズを実現できました。

拡張性#

パフォーマンスの良い言語を使用して元々JavaScript で書かれたツールを再構築することで、より良いパフォーマンスを得ることができます。しかし、これは通常コストがかかります。Rust で書かれた lint ツールは一般的にルールを簡単にカスタマイズできないため、ESLint コミュニティで非常に人気のあるルールだけが移植されることになります。これは、React Compiler のリリースに伴うeslint-plugin-react-compilerのような公式にリリースされた ESLint プラグインをすぐに利用できないことを意味します。また、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-stagedsimple-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 のブレイキングチェンジによる問題も、さまざまな方法で解決できます:

  1. 上流のプラグインに PR を作成して ESLint v9 に適応させる。多くの場合、数行のコードを変更するだけで、ESLint v9 で新しい API を使用し、古い API を互換性のために保持できます。
  2. 一時的に ESLint v8 を使用し、プラグインが適応するのを待つ(依然として Flat Config を使用できます)。
  3. 公式が提供するESLint Compatibility Utilitiesを使用してアップグレードを手助けします。

结语#

再度強調する必要がありますが、これは私の個人的な感想と見解であり、考慮が不十分な点があるかもしれません。ぜひあなたと交流したいと思いますし、あなたの見解を共有していただければと思います。

もし今 ESLint All In One を試してみたいのであれば、Anthony Fu の ESLint config から始めることを強くお勧めします。これは非常に多くの言語とフレームワークをサポートしており、その上で柔軟に設定を行うことができます。

もしあなたが主に TypeScript と React を書くのであれば、私の ESLint config を試してみることもお勧めします。私のルール設定の哲学は、できるだけプラグインのプリセットルールを使用し、その上で自分の習慣に合わせて調整し、stricttypeCheckedオプションを提供して異なるレベルの調整を行うことです。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。