技術ブログのような何か
About | Profile | Diary | Application | Source Code | RSS
投稿日時 2026-05-30 02:16:34 +0900 | カテゴリー 技術
前の記事 Godot でソート可視化ツールを作った | 次の記事
jira_issue_url_generator という GitHub Pages でホストしている自作の Web アプリがあります。 React.js で実装していたのですが、この度 npm package をすべて削除して素の HTML ベースに実装しなおしました。 何故そんなことをしたのかを備忘録として記録します。
理由は単純で、昨今のサプライチェーン攻撃への対策です。
ある1つの npm package が侵害されて、それを踏み台に依存するパッケージが次々に攻撃されるニュースを最近見かけます。 npm package は依存が深く、1つパッケージを追加するだけで、大量の依存性が追加されたりします。 そのため、1つの侵害が複数のプロジェクトに波及しやすい性質をもっています。
jira_issue_url_generator も、それなりにパッケージを入れていました。
仮想 DOM フレームワーク+よくある周辺ツールという感じですね。 そこまで多くありません。 ですが、実際にはこれらのパッケージから合計で 963 個もの依存性が発生していました。
自分用に作った小さなアプリでこれだけの依存があるのは、いくらなんでも多すぎました。
一応、dependabot で依存パッケージのバージョンを最新に保つようにはしていましたが、 自動マージするようにしていても、大量の PR が作られます。 自動マージなのでほとんど見ていなかったですが、メジャーバージョンが上がったりするとマージされず、自分で確認しないといけません。 そういう小さな対応が嫌になりました。
そもそも、このアプリは React.js の勉強目的で作りはじめたものでした。 当時はまだ React.js に興味があったため、趣味で作りたかったアプリに React.js を採用したのです。 実際、採用したことで React.js の理解は深まったので、無意味ではなかったです。
逆にいえば、アプリが完成した時点で、React.js を採用した目的を達成してしまったので、React.js のまま保守しつづける意味がなくなったのです。
仮想 DOM フレームワークが必要なほど大規模なアプリではありませんでした。 素の HTML と JS で実装しても、そこまで負担にならないと思うようになったため、 それならいっそ全部ひきはがすことにしました。
まず、何をどこまで捨てるか整理しました。 React.js と TypeScript はまず捨てるとして、他は悩みました。 ユニットテスト、静的解析、フォーマットのどれも捨てがたいです。
これら3つは残すか、と思いましたが職場の同僚に Deno を教えてもらって解決しました。 Deno は Node.js のランタイムで、ユニットテストフレームワーク、静的解析、フォーマットを内包しています。 おまけに TypeScript も備えていました。文句なしでこれしかないと判断しました。
方針が確定してからは簡単でした。 まず public ディレクトリ配下に手書きの index.html を作成し、ユニットテストしたい関数を JavaScript ファイルとして切りだして作成。 tests ディレクトリにテストコードを書いて public ディレクトリのファイルを相対パスで参照。 CSS は TailwindCSS を CDN から取得。万が一ファイルが改竄された場合に備えて integrity 属性も付与。 あとは適当に python の http.server でローカルサーバーを起動して動作確認しながら修正しました。
最後に package.json と package-lock.json を削除して、完了です。
リポジトリが非常にスリムになって大満足です。 あと久しぶりに素の HTML を書いた気がします。 仕事で触るのは、React.js や Vue.js 、テンプレートエンジンなどの複雑なものばかりだったので。
ただ、大変さもやはり感じました。 特に感じたのは、やはりコピペコードの多さです。 ほとんど同じフォーム要素の連続は、すべてコピペ実装になっています。 TailwindCSS のクラスを複数箇所にまったく同じように付与するのは、修正もれを誘発する危うさがあります。 こういうのはフレームワークのコンポーネント実装で共通化できるのがうらやましいです。
今回みたいな単純な実装は、ペライチの個人アプリでなら通用しますが、 複数人で開発する仕事では通用しないと思います。
まぁ、社内用で画面数が多くないアプリならもしかしたらありかもしれません。 とはいえ、その場合でも仮想 DOM フレームワークをいきなり採用するのではなく、 サーバサイドの Go のテンプレートエンジンで生成するなどで十分な可能性もあります。
「とりあえず何のフレームワークを採用するか」から考えるのではなく、 そもそも採用しない選択が思いうかぶようになったのは、今回の移行を経てえた最大の学びでした。
以上です。
前の記事 Godot でソート可視化ツールを作った | 次の記事