Webpack → Vite: バンドラーマイグレーションの話
(engineering.ab180.co)サービス公開後5年間使っていたWebpackをViteへ移行する中で起きたことを共有します。至らない点も多いですが、楽しく読んでいただけたら幸いです。
Webpackの長所とWebエコシステムの変化
Webpackはこの10年間にわたって開発・管理され、エコシステムがよく整っています。
Create React App など多くの場所でも使われており、IIFE方式でモジュールを束ねることで複数のブラウザをサポートします。
しかし、5年間でサービス内の機能が3倍近く増え、ビルド時間が伸びるなど開発体験が悪化しました。そしてWebエコシステムの進化により、ES Moduleのサポートなどさまざまな変化がありました。
Bundler + Native
ここ1〜2年ほどで、Nativeの力を借りてバンドリングやトランスパイルを行う流れが注目され始めました。シングルスレッドであるJSの処理限界を超えるための試みが進められています。
Golangベースの esbuild、Rustベースの SWC などが代表的です。
1回目の試み: esbuildだけを使ったバンドリング
当時は安定性やプラグインなどエコシステムを考慮し、esbuildをベースにしたバンドラーを使うことに決めました。そして、esbuild自体の性能がどの程度なのかを確かめようとしました。
パッケージをインストールしてビルドスクリプトを実行すると、従来は約210秒かかっていたビルドが2.16秒で完了しました。およそ100倍速いビルド速度を示しました。
しかし、EmotionJSを使うために Babel を適用すると10倍遅くなりました。
また、esbuildはHMRをサポートしていないため、実用は難しいと判断しました。自分たちでHMRを実装することもできましたが、工数や保守・運用・管理コストが大きいと考えました。
2回目の試み: Viteを使ったバンドリング
Vite のコンセプトは、Dependencies と Source code を分離することです。
Dependencies はインストール後に内容が変わらないため esbuild で事前にトランスパイルします。Source code は頻繁に変わるため ESM で読み込みます。ビルド結果はキャッシュされるため、高速な開発ビルドが可能になります。
Viteが提供するテンプレートを使って簡単にマイグレーションを進めました。いくつか問題はありましたがすぐに解決でき、Webpackよりはるかに短く簡潔な設定にできました。
バンドラーマイグレーションの結果
Netlifyでビルド時間を測定したところ、平均250秒 → 平均90秒。従来の36%水準まで削減されました。
設定ファイルが簡潔になったことで、チームメンバーがこれを活用したカスタムビルド環境を容易に作れるようになり、効率が向上しました。
さらなる改善のために、Babel依存のないCSS-in-JSライブラリへの置き換えや、Monorepoの適用も検討できます。
エコシステム面では、SWCが安定化すればBabelを置き換えられるはずであり、TypeScript Type CheckerもNativeへポーティング中です。
教訓
- 大きく見える作業も小さく分けてテストし、十分に議論すれば解きほぐせる。
- 今メジャーに使われているツールも、エコシステムの進化によってすぐに消えることがある。
- 優れたアクセシビリティが良い環境を作ってくれる。
3件のコメント
esbuild の速さには驚かされますね。
esbuild のメインホームページでも 10〜100 倍速いことをアピールしているのを見て半信半疑だったのですが、実際に見ると衝撃的でした!
私もそんな時代が来るのを本当に楽しみにしています! 本当に開発しやすくなりそうですね :)