なぜ依存関係の削減は難しいのか
e18eも含め、依存関係の削減は素晴らしい取り組みです。
依存関係を削除すれば、Renovate / Dependabot のPRは減ります。 セキュリティ上の影響範囲が小さくなるのはもちろん、調査や追従の負担も減ります。 開発体験の改善に加え、本番パフォーマンスが向上することもあります。
とはいえ、道のりは平坦ではありません。いまだに多くのリポジトリがjestのままであることからも、それはよく分かります。なお、こうした課題は他の言語でもかなり共通しています
よくある課題
社会的なもの
まずはこれ。というかこれがすべて。
機能以外に関心が向きにくい
ほとんどのメンテナやコードオーナーは、依存関係や非機能要件そのものには強い関心を持っていません。 忙しさもあり、関心はどうしても機能追加に集中しがちです。
PR作成者への信頼がない
よく知らない人からのPRは、レビューされずに流れてしまうことも少なくありません。 AIの時代はなおさらです。まずは信頼を得る必要があります。
リポジトリごとに進め方が違う
そのままPRを送ってよいリポジトリもあれば、先にissueを立てる必要があるものもあります。 やり方を読み解くだけでも負担です。書いてあるだけまだ親切で、実際には空気を読む必要があることも多いでしょう。
結局リリースしないといけない
とくにほぼ保守されていないリポジトリでは、変更そのものよりもリリースが負担になります。 使われている限り、改善して終わりにはできません。
そもそも該当リポジトリに関心がない
最終更新が何年も前だったり、組織内でインセンティブがなかったりすると、改善は進みません。
AIを使っても結局レビューは必要
外部ライブラリの一部だけを使っている場合、AIでinline実装を書き下ろすことも可能です。 とくにレガシー依存の削除には有効です。ただし、最終的なレビューの負担は依然として重く残ります。
オーナーシップが曖昧
複数メンテナのリポジトリでは、依存関係の変更を誰がレビューするのか定まっていないことが多く、結果として放置されがちです。
やっている人がまだ少ない
依存関係削減はまだ開発の常識とまでは言えず、毎回その意義を説明する必要があります。理解コストが高いのも課題です。
技術的なもの
AIになんとかしてほしいもの。
現実的に互換性の担保が難しい
lodashの部分置き換えやネイティブAPIへの移行でも、微妙に仕様がずれることがあります。 100%互換でないと不安が残り、検証コストが増えたり、PRが見送られたりします。
バージョンアップでも不具合は起こりうる
e18e対応により依存関係が一気に減ることがありますが、マイナーバージョンアップであっても不具合が出る可能性は否定できません。 ライブラリ単体だけでなく、相互作用が原因になることも多いです。
テストが薄く、自信を持ちにくい
テストは後回しになりがちです。 リグレッションテストが不足していると、「本当に大丈夫か」を確信できません。
効果が分かりづらい
単一ライブラリの削減では、パフォーマンス改善のインパクトが小さいことがあります。 また、transitive dependencyの影響で、明示的な依存を削っても最終的な構造が変わらない場合もあります。
パフォーマンス改善ではよくあることですが、小さな改善を積み重ねて初めて大きな効果が現れることがあります。 しかし、そのためにエコシステム全体を改善していくのは手間がかかります。
複雑なものしか残っていない
単純な修正の後に残るのは複雑な依存です。 Aを直すためにB、そのためにCとDを…というドミノ的な修正が発生します。
影響範囲に自信を持ちづらい
とくにモノリポでは、依存削除の影響がどこまで及ぶかの把握に時間がかかります。無関係に見えるscript類もやっかいです
削減しても再び増える
大きな労力をかけて削減しても、依存関係は簡単に再び増えていきます。
やり方おすすめ
完全に削除する
knipなどで影響範囲なく削除できる場合は最も簡単です。文字通りノーリスクです。
小さく分けて送る
レビューしやすく、信頼も得やすくなります。ただしレビューとリリース回数は増えます。
AIで代替実装を作る
大技ですが有効です。古いしがらみを断ち、新しく作り直したほうが進むこともあります。 ただし採用やコミュニティとの関係には注意が必要です。
予防する
依存関係は削るだけでなく、増やさない仕組みも重要です。 以下のようなツールでガードレールを設けるとよいでしょう。
最後に
依存関係の削除であっても結局他の開発と同じような課題が浮かび上がります。AIが全部やってほしいですね
P.S. このあたりに関連して、こんなツールも作りました。