FLINTERS Engineer's Blog

FLINTERSのエンジニアによる技術ブログ

GANMA!管理画面で Create React App から Vite に移行した話

こんにちは。生田です。
この記事は FLINTERSのカレンダー | Advent Calendar 2022 - Qiita の21日目の記事です。
今回は、GANMA! の管理画面で Create React App から Vite へ移行した話をご紹介します。

背景

GANMA! の管理画面は React で書かれており、プロジェクトはCreate React Appでセットアップされていました。
Create React App は React で Web アプリ作るときにビルドツールやリントツールなどのセットアップを1コマンドでやってくれる便利なツールです。
HMR なんかも何も設定せずにnpm startをすればよしなに動いてくれます。
機能も多くしばらくは困ることなく使っていました。
しかし、ある程度の期間利用しているととある不満が出てきました。

それは開発サーバーの起動が遅いということです。
npm startから約40秒後に開発サーバが立ち上がる状態でした。
遅すぎるというほどでもないですが、地味に長い時間です。
(私はいつもこの時間を使いネスカフェのドルチェ グストでコーヒーを入れるなどしていました)

そして、開発サーバー起動遅い問題を解決できるのではと移行先候補に上がったのが Vite でした。

Viteとは

Vite | Next Generation Frontend Tooling

Next Generation Frontend Tooling ... とのことです(これだけだとよくわからない)。
詳細は公式サイトにも書いてありますし、すでに世の中には多数の記事が存在するのでここでは詳細は記述しないこととします。

Vite を選んだ理由

  • 開発サーバーの起動が速い
  • 必要な機能が揃っている
  • 開発が活発
  • ドキュメントが整備されてる
  • Rollup プラグインエコシステムに乗っかれるのでプラグイン周りの心配は少ない
  • ある程度知名度がある・流行っている

他の候補としては snowpack もありましたが、
snowpack は開発が活発ではないようで README には

Update (April 20, 2022): Snowpack is no longer actively maintained and is not recommended for new projects.
Check out Vite for a well-maintained Snowpack alternative.
(意訳)開発が活発じゃないから新規プロジェクトでの採用はおすすめしないよ。代わりに Vite をチェックしてみてね

といった旨のメッセージが書かれており候補とならずでした。

知名度や流行具合については GitHub のスター数やThe State of JS 2021 、 zenn・Qiita・企業ブログ などに記事があるかどうかなど眺めて把握しています。
また、知名度や流行具合については、流行っていることにより「開発が継続される可能性が高い」「問題があった時に調べやすい」「他での利用実績があり比較的安心」などのメリットがあると考え、あくまで選定候補のポジティブな要素の一つであると捉えています。

移行手順

詳細を書きたいのですが物量的に厳しいので参考になりそうなリンクを貼ってお茶を濁しておきます(ゆるして

実施時には主に1つ目のリンクのものを参考にしましたが、 記事がやや古く、deprecated となった@vitejs/plugin-react-refreshなどを追加する手順が書かれていたりするのでご注意ください。

躓きポイントもいくつかあったのでご紹介します。

popperjs などのライブラリが global を参照してエラーになる

global is not definedと言われてしまいます。

この件は vite のリポジトリで issue が立っていたため参考にして直しました。
`global is not defined` · Issue #2618 · vitejs/vite · GitHub

<script>
  // cf. https://github.com/vitejs/vite/issues/2618#issuecomment-820919951
  var global = global || window;
</script>
react-virtualized で No matching export エラー

vite で dev サーバーを起動しようとすると以下のようになってしまいました。

✘ [ERROR] No matching export in "node_modules/react-virtualized/dist/es/WindowScroller/WindowScroller.js" for import "bpfrpt_proptype_WindowScroller"

    node_modules/react-virtualized/dist/es/WindowScroller/utils/onScroll.js:74:9:
      74 │ import { bpfrpt_proptype_WindowScroller } from "../WindowScroller.js";
         ╵          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

この件は react-virtualized のリポジトリで issue が上がっています

Bogus import in generated dist ESM file · Issue #1632 · bvaughn/react-virtualized · GitHub

どうやら react-virtualized のビルド生成物に不要な import 文が紛れ込んでしまい(何故…)、
しかもその対象が export されていないために出ているエラーのようです。

webpack では無視されていたらしく、vite にしたことで問題が顕在化した形のようです。
issue を見るに、react-virtualized の開発者が反応をしてくれておらず修正版のリリースがされていないようです。

react-virtualized を剥がすのも大変なので、今回は issue 内のコメントでも紹介されているpatch-packageを使う方法で回避しました。

詳細はpatch-packageのREADMEを見て頂ければと思いますが、
一言でいうとpostinstallのタイミングで、不要な import 文を消すパッチを適用している形です。

この件はあんまりスッキリした解決ができずでした。
今後、リストの仮想化などするときは別のライブラリを探すかもしれません。

(リストの仮想化については パフォーマンス最適化 – React でも言及されているので適宜ご参照ください)

移行結果

諸々の移行作業を終えた結果、以下のようになりました。

(数値はおおよそです。正確な測定結果として参照しないようお願いします)
(テストは Vitest に移行しています)
(計測はそれぞれ3回実施して平均を出しています。HMR が体感なのは許してください…)

移行前後の速度の比較

開発サーバーの起動が爆速です!! やりました!!
他にもビルドなども若干速くなっており、そこは想定外でした。
できれば理由を明確にしたいのですが時間の都合上そこはできていません。
それと、 Vitest に移行したテストですが、 no-cache で動かしているつもりでも cached 並の速度となっており、
爆速なのか設定をミスっているかが正直わかりませんのであまり参考にしないでください。

まとめ

やや苦労する点もありましたが、無事に vite への移行を終えることで開発体験がかなり向上したと思われます。

開発サーバーの起動の遅さに悩まされている方はぜひ導入を検討してみては如何でしょうか。