😎

MonorepoをBunに移行してみた正直な感想

に公開

最近、Intlayer(i18nソリューション)という、複数のアプリ(Next.js、Vite、React、design-systemなど)で構成されたmonorepopnpm から Bun に移行しました。

結論(TL;DR):もし事前に知っていたら、多分やらなかったと思います。
数時間で終わると思っていましたが、実際には約20時間かかりました。

「オールインワン」という約束と、驚異的なパフォーマンスベンチマークに惹かれました。
セットアップしてビルドしてみると、とにかく速い。最高!
そしてコミットした瞬間……最初の問題に遭遇しました。


Huskyが動かなくなった

commit-msgpre-commit ファイルに、手動でBunのパスを追加する必要があることが判明。
ドキュメントには一切記載なし。
GitHub Issuesを掘り下げて、ようやく回避策を見つけました。

次は GitHub Actions
変更 → プッシュ → 待機 → 確認 → 修正 → 繰り返し × 15回。
キャッシュの問題をデバッグするのに3時間もかかりました。
ようやくすべてビルド成功。
さて、アプリを起動……と思ったら、また問題発生。


バックエンド(Backend)

問題1:
express-rate-limit を使用すると、すべてのリクエストが失敗。

問題2:
アプリでは express-intlayer を使用しており、これはコンテキスト変数に cls-hooked を依存しています。
しかし Bunはcls-hookedをサポートしていません。

解決策: Bunでビルドし、Nodeで実行する。


ウェブサイト(Website)

問題1:
ローカルではビルド成功したものの、公式のBunイメージを使ったコンテナ内ではビルドが無限にフリーズ。
CPUが100%に達してサーバーがクラッシュ。
結局ロールバックする羽目に。
2023年のGitHub Issueで「Nodeのイメージを使い、Bunを手動でインストールする」方法が紹介されていました。

問題2:
Design systemのコンポーネントが「module not found」エラーを出し始めた。
Bunはまだパッケージパスの解決に問題があります。
createRequire の呼び出しをすべて置き換え(CJS/ESM互換のため)、必要な関数ごとに require を手動で渡す必要がありました。

他のエラーは省略します。


何時間も格闘した末、ようやくすべてが動くようになりました。
では、CIのパフォーマンス改善はどうなったでしょうか?

項目 以前 Bun移行後
Backend CI/CD 5分 4分30秒
Server MCP 4分 3分
Storybook 8分 6分
Next.jsアプリ 13分 11分

実行時は、ExpressとNext.jsアプリの両方が依然としてNode上で動作しています。


結論

「今、Bunに移行すべき?」と聞かれたら、私の答えはこうです:

動くことは動くが、複雑なケースにはまだ本番環境向けではない

それでも、Bunには大きな可能性を感じており、これからの進化がとても楽しみです。

あなたは移行の際に同じような問題に遭遇しましたか?

Discussion