VueをReactにリプレイスしてEasyからSimpleにした話
はじめに
こんにちは、株式会社マイベストでフロントエンドのテックリードをしているteppeitaです。
弊社が運営している mybest の技術スタックをVueからReactに移行したので、その時の話を共有したいと思います💪
mybestのフロントエンド紹介
まずはイメージしやすくするために、簡単にmybestのフロントエンドについてご紹介します。
フロントエンドの技術構成
- TypeScript
- React
- ApolloClient(APIがGraphQLです)
- Storybook(VRTやinteraction testsを実行しています)
- Jest
- Cypress
↑少し前まで、ReactのところがVueでしたが、リプレイスしました。今回はその話です。
画面構成
mybestには、大きく分けて、フロント画面(一般ユーザーが見る画面)と管理画面が有ります。
そのうち、Vueで表示されていたのは以下の画面です(それ以外はRailsのslimを使って表示しています)
- フロント画面:商品ランキングの表示や操作
- 商品ランキングは、表示切り替え機能が有ったり、絞り込みなどのAPIリクエストが走る操作があります
実際の画面です
- 商品ランキングは、表示切り替え機能が有ったり、絞り込みなどのAPIリクエストが走る操作があります
- 管理画面:コンテンツや商品情報の編集画面全般でした
- コンテンツの編集画面はセクションごとにページ分けされた独自CMSとなっています
- 商品情報は別で管理しており、カテゴリごとに違うデータを管理しつつ、正規化のために複数テーブルが組み合わさっていたりするので、一般的なメディアサイトよりもかなり複雑度が高いです
- 画面数は25画面ほどで、ほぼ全ての画面で編集機能がありました(=state管理やAPI通信が必要)
- コンテンツの編集画面はセクションごとにページ分けされた独自CMSとなっています
リプレイスにかけたリソース
- 現在、フロントエンドエンジニアは正社員3名、業務委託(副業)4名です
- エンジニアはビジネス課題7割、技術課題3割の配分で時間を使うことができます
- 技術課題3割の時間を使い、9ヶ月ほどかけて(ほぼ)全てのVueをReactへリプレイスしました 🎉
VueからReactへリプレイスした理由
面接などでよく聞かれるのですが、VueからReactへリプレイスした理由や背景をまとめると以下のような感じです!
周辺ライブラリとの相性
当時はVue2系を使っていたのですが、他のライブラリの実装で苦労することが多かったです。(TypeScript、Storybook、ApolloClientなど)
多くのツールはReactを前提に作られている(pluginなどでVueに対応している)ケースが多く、Reactの方が恩恵を受けやすいのではと思っています。
ReactやNext.jsの進化
React HooksやNext.jsのISRが登場して話題になったり、Vercel社に著名なエンジニアが多く採用されていたりと、エコシステム全体としての将来性を感じました。
フレームワークとしては数年前までNuxt.jsがリードしていた印象でしたが、近年はNext.jsと大差ないように思います。(用途によっては逆転?)
EasyとSimple
よく言われることに「VueはEasy、ReactはSimple」というものがあります。
マイベストでVueが導入されていた背景として、当時はチームの人数構成としてバックエンドエンジニアが多かったので、バックエンドエンジニアでも扱いやすいEasyなVueを選択していました。
しかし選定当時から状況が変わり、一時期フロントエンドエンジニアが不在の時期が有ったりしました。
そのため、Vueの設計・運用が難航し始め、将来的な設計・運用のしやすさも考えるとSimpleに保ちやすいReactの方が良さそうに思えました。
※今もバックエンドエンジニアが(任意で)フロントエンドの実装も行います
Vue3への置き換えコスト
当時Vue2系を使っていたのですが、Vue3が出てきて、「Composition APIは良いぞ」と話題でした。
しかし、少し調べたところ、Vue2→3のバージョンアップはかなり修正コストがかかりそうでした。
Reactに置き換えるのと大差ないのでは?ということになり、ゼロベースで比較検討しました。
以上の理由により、メリットが大きくデメリットは小さそうだと判断し、Reactへのリプレイスを決定しました。
※マイベストの技術的な意思決定は、おおよそエンジニア(ないし開発部またはCTO)に一任されています
この辺りに参考文献などを置きたかったのですが、手ごろなのが見つけられなかったので、本記事の執筆中に公開された良さげな記事を貼っておきます🙏(?)
移行プロセスや工夫したポイント
ディレクトリについて
- src/react/というディレクトリを切りました。
- Vueと区別し、linterの設定などを柔軟にできるようにしました
- ディレクトリの切り方としてイケてないですが、移行期に限定すれば扱いやすかったので良かったかなと思っています
- 今思えばmonorepoを検討しても良かったと思います
- 現在は区別の必要が無くなったのでディレクトリ再構成中です
ApolloClient
- Vueでも使っていたのですが、Vue依存のライブラリ(vue-apollo)をやめて、API通信部分のロジックを大部分そのままReactでも使えるようにしました
- (ApolloClientのhookを使うようにしたので、そこは追加実装必要でしたが)
- 一部axiosを使ってREST APIを叩いていた箇所も全てApolloClient・GraphQLに置き換えました
画面単位での移行
- まず、ビルド環境を整理してVueでもReactでも実装・ビルドできるようにしました
- そして移行は画面単位で行うことにしました
- もともとVueが画面単位で書かれていた(=SPAではなかった)ので、これは簡単でした
- これによって、ビックバンリリースを避けつつ、VueとReactが下手に交わらない形で進められました
実装レベルの設計は、まず1ページ実装しながら検討
- 設計を考える時に、大まかな構想や一般論ベースの検討はできますが、ドメインに依存したような詳細な設計は簡単では無いと思います
- そこで、まずは試験的に1ページ実装を始めてしまって、実装しながら細かい設計を行いました
- すると、実装前は見えていなかった特殊な要因が見えてきて、それを確認しながら設計を進められるため効率良く進められました
- 1ページの実装である程度設計を固め、多くの画面で使い回せるコンポーネントや関数を定義し、その後各画面に展開しました
移行してみてどうだったか
設計は難しいが、移行はもっと難しい
- 移行前提だと、ゼロベースで設計することよりも考慮が必要なポイントが多いです(特に移行途中の対応など)
- それに伴い、例えばスケジュールを考える時に、移行期間のことも考慮してかなりの余裕を持たせる必要が有ります(した)
React移行後は色々とSimpleに考えやすくなりました
- 品質を上げやすくなった実感があります
- 一例を挙げると、、、
- hooksを使って副作用を分離しやすく、やはり設計をシンプルに保ちやすい
- また、custom hooksはコードに統一感が出るため可読性・保守性を高めやすいですね
- 各種設計論が(公式・個人ともに)ネット上でも活発なので色々と参考にしやすい
- useEffectのアンチパターンが 公式ドキュメントにある など、
- hooksを使って副作用を分離しやすく、やはり設計をシンプルに保ちやすい
- 一例を挙げると、、、
- 周辺ツールも使いやすいため、色々と導入が捗っています
- StorybookやApolloClientを使うときに、Vueプラグイン独自の何かを気にしなくて良くなりました。
- ApolloClientのモックを使ってStorybookで画面単位の表示をしたりできています(Vueの時にやろうとしたらかなり時間がかかりそうで断念してました)
- 何よりReactは楽しい!
- (※個人の感想です)
今後について
- Next.jsを導入して全画面React化するプロジェクトが動いています(現在は約半分の画面がRailsのslimを使用)
- i18n対応してグローバル化も見据えています
- また、Reactに移行して扱いやすくなったStorybookを使ってフロントエンドのテストを運用し始めています
- JestやCypressも使っていますが、Storybookが中心になりそうです
この辺りはまたの機会にご紹介できればと思っていますが、もしご興味ある方はカジュアル面談も受け付けています!(テーマ設定してますが、別の話でも大丈夫です)
弊社の採用サイトもご興味あれば是非覗いてみてください!
最後までお読みいただき、ありがとうございました ✨
株式会社マイベストのテックブログです! 採用情報はこちら > notion.so/mybestcom/mybest-information-for-Engineers-8beadd9c91ef4dc2b21171d48a4b0c49
Discussion