AI駆動開発のお供にknipがステキな理由
この記事の目的
Claude Codeでvibe codingをしていたときにknipを併用したら体験がとても良かったのでシェア
knipを使っている人が一人でも増えたら嬉しいです。
knipとは
- Typescriptプロジェクト用のデッドコード検知ツール
- 未使用のファイル/関数/exportをいい感じに削除してくれる
- 未使用のcss assetsや不要なpackage.jsonのライブラリも整理してくれる(らしい)
-
ts-pruneやunimportedの後継
- どちらもpublic archiveになっており、「knipを使え」とのアナウンスがでている。
- zero-configで使える
-
npx knipだけでプラグインの用意されたプロジェクトなら解析できる -
多くのプラグインが提供されており、Next.js、Nuxt、Expo、Nest.jsなどのフレームワークだけでなく、babelやbiomeのビルドツールやjestなどのテストフレームワークのエントリポイントも解析してくれる
- 個人的にはGithub Actionsのプラグインがお気に入りです。ci上で実行しているツールもエントリポイントとして解析してくれるのがアツいです
-
AI駆動開発のお供に何が嬉しいのか
コーディングエージェントが書き散らかしたコードを掃除してくれる の一言につきます。
「とりあえず動いてくれればいい」くらいの要件のものをコーディングエージェントに丸投げして作らせることは昨今よくあると思います。
t-wadaさんのAI時代のソフトウェア開発を考えるでは「AIに委託」と表現される区分のものですね。
しかし、シンプルなものでもコードサイズが微妙に大きくなってくると、デッドコードにコーディングエージェントが「引っ張られて」、
実際には使われていないコードの修正を行ったり、勘違いした仕様理解をすることが散見されました。
(人間が仕様を理解する負荷も増えていました)
サブエージェントにcodeをclean upさせるなりすれば多少は解決するようですが、ツールで解決できるものはツールにさせたほうが速度・確実性・コストの面で優れていると考えています。
(余談ですが、私は最近Claude Codeのlimitを最近よく踏みます)
clean up用のサブエージェントにlintツールの一部としてknipを使わせるのがベストプラクティスかもしれません。
knipは非常によくできたzero-configの仕組みを持っており、大抵のプロジェクトではほとんど学習コストを掛けることなく利用することができます。
せっかくなので、ここでknipがどのような仕組みでzero-configを実現しているのか、簡単に解説してみます。
knipがzero-configで動く仕組み
knipは以下のような仕組みで、「プロジェクトのエントリポイントの設定をしなくても動作する」という優れた仕組みを持っています。
package.jsonやディレクトリ構成から使うべきプラグインを自動判定
最初にknipはプロジェクトを解析し、必要となるプラグインを自動で決定します
例えばpackage.jsonに「next」を含む場合はNext.jsのプラグインが自動で有効になり、
.github/workflows に.ymlや.yamlがある場合はGithub Actionsのプラグインが自動で有効になります。
各プラグインからエントリポイントになりうるファイル / 関数を自動判定
次に各プラグインがエントリポイントになりうるファイル / 関数を自動判定します。
このあたりはかなり素朴に作られており、「これらのプロジェクトがエントリポイントにし得るディレクトリ」をプラグイン内部にハードコードしています。
例えばNext.jsの場合は以下のようなエントリポイントをプラグインに指定しています。
{
"next": {
"config": [
"next.config.{js,ts,cjs,mjs}"
],
"entry": [
"{instrumentation,instrumentation-client,middleware}.{js,ts}",
"app/global-error.{js,jsx,ts,tsx}",
"app/**/{error,layout,loading,not-found,page,template,default}.{js,jsx,ts,tsx}",
"app/**/route.{js,jsx,ts,tsx}",
"app/{manifest,robots}.{js,ts}",
"app/**/sitemap.{js,ts}",
"app/**/{icon,apple-icon}.{js,jsx,ts,tsx}",
"app/**/{opengraph,twitter}-image.{js,jsx,ts,tsx}",
"mdx-components.{js,jsx,ts,tsx}",
"pages/**/*.{js,jsx,ts,tsx}",
"src/{instrumentation,instrumentation-client,middleware}.{js,ts}",
"src/app/global-error.{js,jsx,ts,tsx}",
"src/app/**/{error,layout,loading,not-found,page,template,default}.{js,jsx,ts,tsx}",
"src/app/**/route.{js,jsx,ts,tsx}",
"src/app/{manifest,robots}.{js,ts}",
"src/app/**/sitemap.{js,ts}",
"src/app/**/{icon,apple-icon}.{js,jsx,ts,tsx}",
"src/app/**/{opengraph,twitter}-image.{js,jsx,ts,tsx}",
"src/mdx-components.{js,jsx,ts,tsx}",
"src/pages/**/*.{js,jsx,ts,tsx}"
]
}
}
Next.jsのプラグインのソースコードを見ると、このあたりはわかりやすいですね。
下手にNext.jsプロジェクトに依存させるのではなく、泥臭くエントリポイントとなる知識を自前で持ってしまうのが小賢しくなくて素敵だと思います。
プロジェクトのエントリポイントからツリーを辿り、未使用のコードを検知
あとは従来のts-pruneなどと同等、エントリポイントからツリーを辿り、未使用のコードを検知します。
ASTの解析にts-morphを使わずに TypescriptのネイティブAPIを呼ぶなど、
パフォーマンス改善のための攻めた工夫もなされているようですが、1ユーザとして利用する上では特に意識する箇所ではないので今回割愛します。
おわりに
knip、というよりデッドコード検知のOSSとして「自身が絶対に負債にならない」という矜持があるようで、コードを汚染しないようにあえて disableコメントが無い という思想の強い設計になっているのも素敵だと思います。
(knipとその起動コマンドとコンフィグファイルを消せばクリーンアップが完了する様になっています)
AIツールのキャッチアップに皆忙しいし、AIにツールの使い方を教えるのも手間なので、ツールがzero-configであることの価値は以前より高まってきた気がします。
紹介した通り、knipは「簡単に使えて簡単に捨てられる」仕組みになっているため、AIコーディングのお供に気楽に導入してみることをおすすめします。
こういったツールはAI時代の今こそバリューを発揮しやすくなったように思えます。最近ではAI以外のツールの情報をキャッチアップする機会が減ってしまいましたが、たまにはこういう純粋なツールの話も楽しいですね。
余談ですが、開発者がブログで「俺達はコードが消える赤い芝が増えるのが喜びなんだ!」といっているように、本当に雑然としたコードをクリーンにするのが好きなメンバーによって運営されているOSSのようで、見ていてちょっとワクワクしました。
当記事は執筆にはほぼAIを用いていませんが、情報収集と解析にChatGPTのDeepReserachを利用しています。
Discussion