EslintからOxlintへの移行 - #337
shinagawa-web wants to merge 17 commits into
Conversation
Replace ESLint with Oxlint across pkgs/typed-api-spec, examples/misc, and examples/vite-react-openapi for faster lint runs and lighter deps. - Generate .oxlintrc.json via @oxlint/migrate and hand-review it against the original eslint.config.js (strict-dependencies depRules, t-test override, react-hooks/react-refresh coverage) - Drop eslint-plugin-react-refresh entirely: its only-export-components rule is now natively implemented by oxlint - Remove eslint.config.js and eslint-related devDependencies; add oxlint - Update test:lint / lint npm scripts to run oxlint
e813753 to
3122e27
Compare
Statically compares each workspace's enabled eslint rule set (severity + hand-authored options) against its .oxlintrc.json, per the migration plan's §A methodology. All four representative files show no unexplained gaps or drift beyond documented oxlint tooling limitations (no-octal, react/config, react/gating).
Compares each workspace's eslint-linted file list (from `eslint --format json`, per the plan's step 1) against oxlint's actual target file list (`oxlint --debug=files`), normalizing paths for a direct diff. All three workspaces match exactly; vite-react-openapi's only difference is the now-deleted eslint.config.js self-listing itself, not a coverage loss.
Scripts the plan's §C runtime checks (previously done ad hoc): places temporary violating code to confirm rules fire where expected and stay silent where excluded, covering behavior static config diffing can't observe — jsPlugin loading (strict-dependencies), varsIgnorePattern, the *.t-test.ts override, ignorePatterns scoping, and react-hooks — across all three workspaces (pkgs/typed-api-spec, examples/misc, examples/vite-react-openapi). Uses trap-based cleanup and a final `git status --short` check so leftover probe files can't slip into a commit. The ignorePatterns "should be excluded" checks use a dedicated check_ignored() that requires the probe file to actually exist on disk in addition to oxlint's "No files found to lint" message — a bare empty grep match can't distinguish "file was excluded" from "file was never created", since oxlint prints the identical message and exit code for both. All 14 checks pass.
Independent review (Codex) re-verified the eslint dump against .oxlintrc.json from a clean clone and confirmed the migration is faithful. Its one substantive finding — react-hooks/config and react-hooks/gating have no oxlint equivalent and were undocumented — is now recorded in the plan's known-unmigratable-rules table alongside no-octal.
…rules" This reverts commit 508aa25.
This reverts commit bbe0f03.
This reverts commit 858dc21.
…ation" This reverts commit 5e04452.
Merging origin/main (zod 4.3.6->4.5.4, @types/supertest 7.2.0->7.2.1) left package-lock.json internally inconsistent — `npm ci` failed with "Missing: @eslint/js@9.39.5 from lock file" even though no package.json references that package anymore. Reproduced the exact CI failure locally (GitHub tests the PR's merge commit against main, not the branch tip in isolation) and confirmed a plain `npm install` after the merge produces a lockfile npm ci accepts cleanly.
|
@claude PRのレビューをしてください |
|
Claude finished @shinagawa-web's task in 6m 8s —— View job PRレビュー報告書(sanity-review)
1. pull request 概要欄サマリー(実装者の説明から抜粋)
品質評価チェックリスト(手順2)
2. 実装者の説明と実装の整合性(手順3)読み合わせで重大な齟齬 3 件、軽微な齟齬 1 件を検出。 🔴 [B-1] PR概要欄の「検証」表と現在のブランチ内容が食い違う(PR body / commit history)概要欄の検証表は §A / §B / §C / §D それぞれのコミット (
意図が「実測は済んだので tmp/ は最終PRに残さない(scratch扱い)」なら、概要欄の文面は「再現可能」→「(scratchで実施済、tmp/はcommit保持せずrevert)」等に修正が必要。もしくは意図に反して revert してしまっている可能性がある(下記 B-2 と併せて検討すべき)。 🔴 [B-2] 「既知の非等価性は plan の『既知の移行不可ルール』表に詳細」と書かれているが該当表が plan doc に存在しない概要欄:
しかし 原因は §D コミット ( 結果として、PR body が指し示している「表」がリポジトリ上に存在しない。ドキュメントとしての整合性が壊れている。 🔴 [B-3]
|
The merge of origin/main (9f5d06b) resolved without conflict but spuriously reintroduced "@eslint/js": "^9.39.5" into pkgs/typed-api-spec/package.json's devDependencies — a line our migration had already removed. Flagged by automated PR review. Removed it again and regenerated the lockfile.
…od rule The src/zod module's allowReferenceFrom carried **/*.test.ts twice — once via the shared dRef spread, once appended explicitly — faithfully copied from the original eslint.config.js. Cosmetic only (duplicate glob entries have no behavioral effect), flagged by automated PR review.
Reverting the verification §D commit (508aa25) also swept away this table's addition to the plan doc, even though it documents a real, permanent migration limitation (no-octal, react-hooks/config, gating) — not a verification artifact. Re-adding just the table, without the verification log that came with it, per automated PR review [B-2].
oxlint-migration-plan.md served its purpose during development (plan, verification methodology, review notes). Its content that matters long-term — the known-unmigratable-rules — is captured in the PR description instead.
…t-migration # Conflicts: # examples/misc/package.json # package-lock.json
|
@claude PRのレビューをしてください |
|
Claude finished @shinagawa-web's task in 5m 41s —— View job PRレビュー報告書(sanity-review・再レビュー)
0. 前回指摘の追跡
前回指摘は全て解消済み。以下、今回改めて全体を通した観点で再レビューする。 1. pull request 概要欄サマリー(実装者の説明から抜粋)
品質評価(手順2チェックリスト)
前回「今やる価値」に定量ベースラインが薄いと指摘した点は、変更内容が最終的に純減 (997/-1340) を実現しており、依存軽減の効果は差分から自明。指摘取り下げ。 2. 実装者の説明と実装の整合性(手順3)概要欄 → 実装の突き合わせ
齟齬なし。前回検出した 3 件の重大齟齬(B-1/B-2/B-3)と 1 件の軽微(B-4)は全て解消済み。 「既知の非等価性」宣言の実装確認
3. 命名・設計パターンの一貫性(手順4)コードベースとの整合
設計パターン
長期視点の考察前回同様、3 ワークスペースそれぞれに もう一点、 4. バグ・脆弱性の調査(手順5)セキュリティ影響のある変更ではない(開発時 lint のみ、ランタイム / 公開 API に影響なし)。バグ観点で気になった点:
5. 対話コンテキストの再読み(手順6)
→ 対話コンテキストなし。手順6はスキップ。前回同様、plan doc(削除済み)が担っていた「方針」「スコープ外」「検証」の要点は現在概要欄に集約されているため、レビュアーは概要欄のみで判断可能。 6. レビュー作業において発生した問題⚠ 警告: 批判的思考の連鎖が機能していません、実行環境が正気である事を疑ってください
7. 結論総合判断: マージ可 根拠:
残る観察点(blocking ではない、将来PR/参考情報):
評価できた点:
|
別PRにて対応します。 |
概要
ESLint を Oxlint に置き換え。対象は eslint 設定を持つ 3 ワークスペース(
pkgs/typed-api-spec/examples/misc/examples/vite-react-openapi)。lint の実行速度と依存の軽さを改善する。変更内容
@oxlint/migrateで.oxlintrc.jsonを自動生成し、元のeslint.config.jsと突き合わせて手直しstrict-dependenciesの depRules・no-unused-varsのオプション(varsIgnorePattern/argsIgnorePattern/caughtErrors)・*.t-test.tsoverride は元設定と一致させたeslint-plugin-react-refreshは完全削除。only-export-componentsが oxlint にネイティブ実装されていたため、jsPlugin として残す想定から変更したreact/rules-of-hooks等)に寄せ、eslint-plugin-react-hooksの依存を削除eslint.config.jsと eslint 関連 devDependencies を削除、oxlint(^1.82.0)を追加test:lint/lintnpm scripts をoxlint .に変更package-lock.json更新検証
lint が「エラーが出ない」だけでは、ルールが静かに落ちて検査が緩くなるケースを検出できないため、以下の観点で担保した(検証用スクリプト・ログはPR外のscratchで実施し、本PRには含めていない)。
--print-config)と.oxlintrc.jsonを、severity・オプションの両方で比較。全ワークスペースで、下記「既知の非等価性」以外の差分なしeslint.config.js自体)strict-dependencies)のロード・varsIgnorePattern・*.t-test.tsoverride・ignorePatterns(dist/docs除外)・react-hooksルールが、それぞれ発火すべき側/してはいけない側の両方で期待通り動くことを実測.oxlintrc.jsonと元eslint.config.jsの突き合わせをレビューさせ、ルールの取りこぼし・除外範囲の意図しない拡大が無いことを確認既知の非等価性(移行不可)
oxlint に実装が無く、今回の移行では埋められないルール:
no-octal(全ワークスペース): oxlint 未実装。@oxlint/migrate --detailsが Unsupported として報告(strict mode下では8進数リテラルは構文エラーになるため実害は低い)react-hooks/config/react-hooks/gating(examples/vite-react-openapi のみ): oxlint のreactプラグインに対応ルールが無い(React Compiler の固定オプションのため設定検証自体が不要という oxlint 側の判断)スコープ外
oxlint-tsgolint)の導入 — 別PRpkgs/docs・examples/viteへの oxlint 新規導入 — 別PRexamples/vite-react-openapiの lint を実行するようにすること(現状も未実行のまま)oxlint-migration-plan.mdは開発中の検討用ドキュメントとして使い、移行完了に伴い削除しました(要点は上記に集約)。