紡Book の勉強ノートに戻る
コードレビュー学習2026.05.11

使ってないファイルが警告を出し続ける — 黙らせるより置き場所を直す(ESLint globalIgnores)

ESLintプロジェクト整理

公開ローンチ前のコード整備で見つけた、誰からも import されてない prototype ファイルを綺麗に隔離した話です。

この記事でわかること

  • live tree に放置された prototype ファイルが ESLint 警告を生み続ける問題
  • eslint-disable を貼るよりファイル自体を移動するほうが筋がいい場面
  • ESLint の globalIgnores でディレクトリを一括除外する書き方

起きていたこと

プロジェクトの frontend/ 直下に、過去のデザイン検討で使った photobook-samples.jsx が転がっていた。中身は React コンポーネントの実験コード:

jsx
function PatternD({ data }) {
    return <img src={data.photo} />;  // ← lint 警告
}

このファイル、どこからも import されていない。それでも <img> 警告を 2件出していた。

/app/photobook-samples.jsx
  67:13  warning  Using `<img>` could result in slower LCP and higher bandwidth...
 319:11  warning  Using `<img>` could result in slower LCP and higher bandwidth...
実体は Git のファイル。DB にもメモリにも無い。ディスク frontend/photobook-samples.jsxリポに残っている。閉じても残る。Next.js の .nextimport が無いバンドルに入らない成果物のディレクトリDocker イメージ.dockerignoreイメージに入れない除外リストはファイルESLint の実行frontend/ を読むimg 警告が 2件実行時の出力。保存しない保存はディスクだけ。.next も Docker も見ないが、lint は frontend/ 配下を全部読む。.dockerignore はイメージの除外リストで、lint の対象表ではない。

「ESLint で無視」の選択肢

ファイルを残したまま警告を消す方法はいくつかあります:

方法 効果範囲
// eslint-disable-next-line を行ごとに貼る その行だけ
/* eslint-disable */ をファイル冒頭に置く そのファイル全体
eslint.config.mjs の globalIgnores にファイルを指定 ファイル単位(設定側で管理)
eslint.config.mjs の globalIgnores にディレクトリを指定 そのディレクトリ配下全部

prototype ファイルみたいな「現役じゃない / でも消したくない」ものに eslint-disable を貼るのは違和感がある。これは「lint ルールが間違っている」のではなく「このファイルがここに居るのが間違い」だからです。

採用した方針: ファイルごと隔離する

隔離の仕方は2通りあります。(1) スキャンルートの外に出します。(2) スキャンルート内に残すが、設定で除外します。

どちらも Git のファイル。DB にもメモリにも無い。リポジトリ(1) docs/photobook-samples.jsxfrontend/ の外ESLint は読まない設定を足さないリポ直下の docs に保存(2) frontend/ESLint はここをルートに読むsrc/ 現役lint するsrc/_archive/旧アプリ本体eslint.config.mjsglobalIgnores で _archive 配下を除外試作は docs/ へ出す。src に残す退避は、設定ファイルの除外リストで外す。無視の宣言は eslint.config.mjs にある。ソースには書かない。

frontend/src/ の中に置いておきたい退避コードは、移動だけでは lint 対象から外れません。このプロジェクトでも、旧アプリ本体を src/_archive/ に退避して globalIgnores 済みにしてある:

js
// eslint.config.mjs
import { defineConfig, globalIgnores } from "eslint/config";
 
const eslintConfig = defineConfig([
    ...nextVitals,
    ...nextTs,
    globalIgnores([
        ".next/**",
        "out/**",
        "build/**",
        "next-env.d.ts",
        // 旧アプリ本体は退避中。lint シグナルを汚さないため除外する。
        "src/_archive/**",
    ]),
]);

globalIgnores の書き方

ESLint 9 系の eslint.config.mjs では、globalIgnores ヘルパーで除外パターンをまとめて宣言できます:

js
import { defineConfig, globalIgnores } from "eslint/config";
 
export default defineConfig([
    ...someConfig,
    globalIgnores([
        ".next/**",          // ビルド成果物
        "out/**",            // export 成果物
        "build/**",          // 同上
        "next-env.d.ts",     // Next.js 自動生成
        "src/_archive/**",   // 退避コード
    ]),
]);

ポイント:

  • glob パターンで書きます(**/* で再帰、*.js で拡張子フィルタ)
  • 配列で複数指定可
  • defineConfig 内に置けば設定全体に効きます
  • 個別の override(特定ルールだけ disable)とは別物

学びポイント

  • live tree に import されないファイル が転がっていたら、それは 「整理されていない」状態。lint warning はそのシグナル
  • ESLint の globalIgnores は 設定側で集約管理できるので、ソース内 eslint-disable を増やすより副作用が見通しやすいです

おわりに

Lint や Formatter は「コードがおかしい」だけでなく 「プロジェクトの整理が必要」 のシグナルになることがあります。

整理の道具として lint を使うと、コードベースの見通しが良くなります。


この記事は2026年5月時点の自分の理解で書いています。仕様や認識が変わってる可能性があります。