🔧

Knipで安心してデッドコードを撲滅する

に公開

1. はじめに

こんにちは。現在、単発バイト・スポットバイト求人サービス「スポットバイトル」のワーカー向けの WEB サイトやネイティブアプリの開発に携わっています横山隼 (@hayatoyokoyama_) です。

本記事では、スポットバイトルのワーカー向け WEB サイト(以下、スポットバイトル WEB) で 「Knip」を使って約 2000 行のデッドコードを削除し、デッドコードが残らないように仕組み化した話をご紹介します。

2. 背景

昨年 2024 年 10 月にリリースしたスポットバイトルですが、アジャイル開発を取り入れ、ステークホルダーのフィードバックを反映しながら機能を改善・拡充してきました。その過程で画面が丸々不要になったり、一時的に導入したが別のアプローチに置き換えられたりで仕様が移り変わることも多く、プロジェクト内に徐々にデッドコードが蓄積していきました。

スポットバイトル WEB では以前からコードの品質を保つために、ESLint の no-unused-vars ルールを有効にしたり、eslint-plugin-unused-importsプラグインを導入したりして、未使用の変数や不要な import 文の削除を行っていました。しかし、ESLint では export された不要な関数や型、さらには使われていない依存関係などは検出できず、プロジェクト全体にデッドコードが溜まってしまっていました。

そこで、ESLint だけでは検出できないデッドコードを自動で検出し、安全に削除できる仕組みを整えようと考えました。

3. Knip の導入

そんな中でデッドコードを自動で検出し、安全に削除するために導入したのが Knip です。 Knip は TypeScript や JavaScript のプロジェクト内で未使用の型、関数、クラス、依存関係などを解析し、削除すべきものをリストアップしてくれるツールです。ESLint では検出できない export されているが使われていないコードも発見できるのが大きな特徴です。

今回 Knip を導入しましたが、Knip 以外にも tsrdepcheckts-prune など代替となるツールはあります。スポットバイトル WEB では設定の容易さ、スター数、更新頻度などから Knip を選択しました。

Knip は「zero config」を目指しており、init コマンドを実行するとプロジェクトにインストールされ npm スクリプトに登録されるため、すぐに使用することができます。

\# Knipの導入
npm init @knip/config

npm スクリプトに登録された knip コマンドを実行すると、Unused filesUnused dependenciesUnused exportsといった形で、デッドコードがリストアップされます。

\# Knipの実行
npm run knip
\# Knipの出力例
\> knip
Analyzing workspace ....
Unused files (3) \# 不要なファイル 3件
constants/metadata.ts
constants/preview.ts
types/utils.ts
Unused dependencies (2) \# 不要な依存関係 2件
@urql/next      package.json:53:6
recoil-persist  package.json:66:6
Unused exports (3) \# 不要なExport 3件
arrayUnique  unknown  utils/array/array.ts:4:14
arrayAdd     unknown  utils/array/array.ts:11:14
arrayRemove  unknown  utils/array/array.ts:18:14
Unused exported types (2) \# 不要な型定義のExport 2件
ButtonCarouselProps  type  components/common/ButtonCarousel/ButtonCarousel.tsx:6:13
ButtonTertiaryProps  type  components/common/ButtonTertiary/ButtonTertiary.tsx:9:13

スポットバイトル WEB でも Knip を実行したところ、約 2000 行のデッドコードを削除することができました。これまで手作業では見逃していた不要な型や関数が大量に見つかり、コードが大幅に整理されました。また、Knip は不要な依存関係の検出もできるため、デッドコードの中に含まれていて実際に使われていない依存関係を特定し、削除することもできました。

GitHubのプルリクエスト画面。62個のファイルに変更があったことを示している。

さらに、これまでユニットテストを実行していた GitHub Actions のワークフローに Knip を組み込み、プルリクエスト作成時にデッドコードを検出する仕組みを導入しました。これにより、導入から現在に渡ってデッドコードが新たに増えることを防ぎ、継続的に整理された状態に保つことができています。

(略)
jobs:
  unit-test:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
    (略)
      # Knipの実行(追加)
      - name: Run Knip
        run: npm run knip
      # 単体テスト実行
      - name: Run Unit Tests
        run: npm run test

4. 文化にする

Knip の導入によりデッドコードを安全に削除できるようになったおかげで、チーム内からもコードの見通しが良くなったとフィードバックをもらっています。

どのツールを使うかはプロジェクトやチームの方針によりますが、重要なのはこれらを ESLint や Prettier、Biome のように開発のデファクトスタンダードとして根付かせることだと思ってます。Knip をはじめとするデッドコード検出のツールを導入することで、「迷わず、安全に、短時間でデッドコードが生まれない仕組みを作れること」をどんどん普及させて、文化として定着させていきたいです。

5. まとめ

本記事では、スポットバイトル WEB で Knip を導入して、デッドコードを検出する仕組みを構築した事例を紹介しました。

Knip は設定もシンプルですし、一度仕組みを整えれば、長期的に開発効率と品質の向上を享受できます。今後もスポットバイトル WEB では Knip を活用し続けたいですし、もし新たなプロジェクトに携わる機会があったらそこでも積極的に普及していきたいです。

このブログが何かの参考になれば幸いです。最後まで読んでいただきありがとうございました。

dipテックブログ

Discussion