本記事はリブセンス Advent Calendar 2025 10日目の記事です。
こんにちは。株式会社リブセンスのsyuukiです。
本記事では、今年私が取り組んだデッドコード検知ツール Knip の設定改善について紹介します。「より踏み込んだコード整理がしたい」という方の参考になれば幸いです。
Knipとは?
Knip は、JavaScript/TypeScript プロジェクト向けのデッドコード検知ツールです。
プロジェクト内の参照関係を走査し、使用されていないファイルや export などを検出してくれます。リポジトリのCIなどに組み込むことで、常にコードツリーをきれいに保つことができます。
Knipの特徴として、ゼロコンフィグ(Zero Config)で動作することに重きを置いている点が挙げられます。導入から実行まで、非常に簡単に行うことができます。
例えば、パッケージ管理に yarn を使用している既存プロジェクトへの導入は、以下のコマンド一つで完了します。
yarn create @knip/config
これだけで必要なパッケージのインストール、最低限の設定ファイルの作成、そして package.json の scripts への登録まで完了します。あとは実行するだけです。
yarn knip
これでデッドコードを検知してくれます。
しかし、ある程度規模の大きいアプリケーションでは、これだけでは不十分なケースがあります。
ゼロコンフィグ運用の限界
前述の簡単な導入だけでも、通常のデッドコードは検知可能です。ここでの「通常のデッドコード」とは、「他のどのファイルからも呼び出されていないコード」 を指します。
プロジェクトの規模が大きくなると、テストコードや Storybook など、「アプリケーションの本番環境では使用しないが、開発には必要なコード」が増えてくると思います。当然、テストコードはテスト対象の関数やコンポーネントをインポートします。
このとき、「テストコードからは参照されているが、本番環境のコードからは一切参照されていないファイル」 があった場合、デフォルトのKnipはこれを検知してくれません。
なぜなら、Knip から見れば「テストファイルから呼び出されている=使われている」と判定されるためです。
これでは、「関連する呼び出しがなくなり、本番では使わず、テストだけが残っているゾンビコード」を掃除することができません。これを検知するには、設定や実行方法をひと工夫する必要があります。
解決策:Production Mode の活用
結論から言うと、Production Mode を使用します。
Production Mode とは、Knip の走査対象を「本番環境に影響するファイル」に絞って実行する機能です。テストコードなどを走査から除外することで、それらからしか参照されていないファイル・コードをデッドコードとして検知できるようになります。
このモードを正しく機能させるには、「どのファイルが本番用で、どのファイルがそうでないか」を Knip に教えてあげる必要があります。
設定ファイル(knip.json)の記述例
具体的には、走査の起点となる entryファイル と、走査対象となる projectファイル の命名規則を設定ファイルに記述します。
{
// ...中略
"entry": ["src/app/page.{js,ts,tsx}!"],
"project": ["src/**/*.{js,ts,tsx}!", "!src/__tests__/**/*.{js,ts,tsx}!"],
// ...後略
}
各設定項目の意味は以下の通りです。
-
entry: 依存関係ツリーのルートとなるファイル(Next.jsの
page.tsxなど)を指定します。 - project: 走査対象とするファイル(の命名規則)を指定します。
「!」マークの役割
ここで末尾や先頭についている !(エクスクラメーションマーク)には、以下の意味があります。
-
末尾の
!(src/...!):- その設定を Production Mode と通常モードの両方 に適用します。
- つまり、本番環境で使用されるファイルに付与します。
- (付けない場合は通常モードのみに適用されます)
-
先頭の
!(!src/...):- そのファイルを 除外 します。
- 上記の例では
src/__tests__配下のファイルを、両方のモードの走査対象から除外しています。
実行
設定ができたら、--production フラグを付けて実行します。
yarn knip --production
これで、本番環境で使われていないコードが検知されるようになります。
ただ、このままだと「テストコードから参照するために export している関数」なども「本番で使われていない export」として検知されてしまうことがあります。
このようなことを防ぐために、productionモードは検知対象を絞ることがおすすめです。
ファイル内の要素が全て参照されないコードはデッドコードであると考えられるため、今回はファイル単位での検知を行います。
これには--include オプションを使用します。
yarn knip --production --include files
これで本番環境から全く使用されないファイルを検知することができるようになりました。
運用例:package.json への登録
最後に、これまでの設定を組み合わせて package.json に登録しましょう。通常モード(exportなどを含む広範な検知)と、Production Mode(本番で不要なファイルを検知)を組み合わせて実行するのがおすすめです。
{
// ...中略
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "eslint",
// 通常モード && Productionモード
"knip": "knip && knip --production --include files",
"test": "jest"
}
// ...後略
}
これで、以下のコマンドを実行するだけで、より厳密なデッドコード検知が可能になります。
yarn knip
その他のおすすめ設定・テクニック
設定ファイルの種類
Knip の設定ファイルは、導入初期の JSON 形式以外にも様々な形式に対応しています。
-
knip.config.jsonc: コメントが書ける JSON -
knip.config.ts: TypeScript 形式
Knip の設定では、「将来使うかもしれないコードを ignore リストに追加する」といった運用が発生しがちです。その際、なぜ除外しているのかをコメントに残せると、後々の負債になりにくいです。
特に knip.config.ts はコメントが書けるだけでなく、型定義による入力補完も効くため、おすすめの形式です。
まとめ
Knip の Production Mode を活用することで、テストコードの陰に隠れていたデッドコードを検知できるようになりました。
年末の大掃除の一環として、ぜひ Knip の設定を見直し、きれいなコードツリーを目指してみてはいかがでしょうか。