リーナー開発者ブログ

リーナー開発者の今を発信するブログです。

リーナー、Nuxt.jsからNext.jsに乗り換えたってよ

こんにちは。

めろたんです。

最近は咳としゃっくりが同時に出るようになってしまってとてもしんどいです。

はい。

今回は、弊社のサービスである、リーナー見積のフロントエンドをVueからReactに乗り換えた話について書いていこうと思います。

まず前提

リーナー見積では、フロントエンドは3つのサービスに分かれており

  1. 買い手向け画面
  2. 売り手向け画面
  3. リーナー運営向け画面

という構成になっております。

リーナー運営向け画面、買い手向け画面、売り手向け画面が一つのバックエンドとつながっている
サービスの構成図

各々Nuxt.jsで作られており、その全てでSEOや初期ページローディングのパフォーマンスをすごく求められるものではないため、CSRで行うように構成していました。

また作り始めた当時、会社やプロダクトがアーリーフェイズであり、そもそもプロダクトがこれで行けるかどうかというのもあったため、何を使って作るかというのは深く考えず、後に作り直すだろうというのを前提でNuxt.jsを選定していました。

VueからReactにのりかえた経緯

正確には Nuxt.js v2 を使っていましたが、Vue2が2023年末にEOLになるという発表がありました。このまま放置するわけにはいかず、対応が必要でした。コンポーネントライブラリとしてVuetifyを利用していたため、Vue2, Nuxt2, Vuetify2 を同時に3系統にあげる必要がありました。

別の問題としてVuetifyに使いづらさを感じていたこともあります。Vuetify自体は、スタートダッシュするには良かったのですが、数年サービスの開発をして細かいところで使いづらいところや、コンポーネントのカスタマイズを行いたいが簡単にはできない。というケースが多くあり、これを使い続けるのもしんどいなということが多々ありました。

また、弊社の別サービスでリーナー購買というのがあります。

そちらはReact(Next.js)を使って作っており、社としてエンジニアのローテや知識の共有等を考えると、Vueを使うことをやめて社で使うWebフロントエンドライブラリはReactに1本化したほうがよいと考えました。

Reactでどう作ったのか

まずReactを使うと言っても、ViteでSPAを構築するかNext.jsを使う等選択肢が色々ありました。

今だとRemixでSPAモードを使う選択肢もあったのですが、当時はまだSPAモードがなく選択肢としてあがることがありませんでした。

またViteでSPAを構築するのであれば、Routerの選定を行う必要があり、React Routerが筆頭候補となるのかなと思いますが、過去にとても苦しい経験がありあまり積極的に選択したくないなというのがありました。

そのなかで、先述通りリーナー購買ではNext.jsを使っているので、あわせてそれを使うことにしました。

コンポーネントライブラリについては、現状すでに顕在化していたカスタマイズが大変という問題がありました。

ここで色や形や挙動が明確に決まっていて、カスタマイズ性の低いコンポーネントライブラリを使用してしまうと同様の問題が発生してしまいます。

そこで shadcn/ui を使って新しくデザインシステム・UIコンポーネント集を作りました。

詳しくは、以前おくはらさんが発表した資料がありますので、参考してみてください。

speakerdeck.com

Vueのコードは全てではないのですが、多くが推奨されていない双方向データバインディング(Propsで受け取ったオブジェクトにそのまま代入する形式)を使用されており、単純にReactに置き換えるというのは難しい箇所が多々ありました。

また現状では不要になったであろうコードも複数あり、それらの精査を行う必要もありました。

そのためデザインやフィーリングも変わる箇所があったり、また意図せず機能が落ちてしまう箇所も多々あったため、丁寧にQAも行いながら移行作業を進めていきました。

リリース手順

一度にすべてを置き換えるのは時間がかかります。ただしく移行できているか、テストを行うのも大変であるため、ユーザー影響すくないものから順にリリースを行いました。

そのなかでメンバーの習熟度も上げ、後続のユーザーへの影響度が高いものも安全に一定の速度をもって移行できるようにしました。

順番としては、

  1. リーナーの社員のみしか触らない、リーナー運営向け画面
  2. 画面数も多くなく、比較的機能数も多くない、売り手向け画面
  3. 一番、画面数・機能数が多く、オプションの機能が多分に含まれる、買い手向け画面

としました。

移行の順番の選定の図

さらに買い手向け画面については画面数も多く、機能も多く含まれているので、まず不要な機能の削除や一画面に入れ込んでいた機能の移動を行い、以降に関するコストをできるだけ削減することにしました。

その後、各画面・機能について段階を踏んでリリースを行うことにしました。

  1. ログイン画面・マイページ
  2. 一部ユーザーのみオプションで提供している主要機能
  3. 全ユーザー利用可能な主要機能
  4. 設定画面等

これら画面・機能単位でリリースするために、AWSのCloudFrontを利用し、現行のNuxt.jsと移行後のNext.jsに振り分けるようにしました。

こうすることで、安全に画面・機能単位でリリースすることができました。

おかげで、大きな問題もなく(少々問題はありましたが、即時対応できる範囲でした)移行を進めることができました。

Reactにしてどうだったか

Vue2からの移行であったというのもあり、とてもシンプルにかけるようになったなと感じています。

Vue2を使っているときは、先にも書きましたが推奨されていない双方向データバインディングを使うことで、とりあえず動かすことができていました。

しかしReactにした結果、その方法は不可能になったので、意図せず他のコンポーネントの表示や制御等がおかしなことになるということがなくなり、問題が発生したときも原因を探りやすくなったかと思います。

またこれはReactにしたからというわけではないのですが、移行を機にチーム内で、こういうケースはこう書いたほうがいいよねというような議論やコーディングルールとまでは言えないですが、約束事のようなものもできたりしたのはよかったなと思っています。

また社の開発チームが週に一度集まって、開発全般について話し合う場があるのですが、そこでもReactの話題をとりあげやすくなり、プロダクトを超えてお互いの知見を共有しやすくなったかなと思っています。

さいごに

今回はフレームワーク移行について結構ざっくりと書かせてもらいました!

『移行するぞ!』と決めてから主要メンバー3人ほど*1で、一年無い位の期間で全移行が完了したのは、だいぶよかったなと思っています。 (個人的な経験上ほぼオンスケでこういった移行作業が完了したのは初めての経験だったので、結構嬉しく思ってます!)

また、Bizチームにもなぜこれを今行う必要があるのかというのを理解してもらって、お互いに協力して進められたことはとてもよかったし、弊社が大事にしているBizDevMixを体現できているのかなと思いました!

このうまく行った理由等もう少し踏み込んだことについては、別途記事なり発表なりできたらいいな〜と考えています!

もうちょっと踏み込んで詳しいこと聞きたいよ!という方がいらっしゃいましたら、ぜひカジュアルにお話できればと思ってますのでよろしくお願いします!

pitta.me

*1:時期によっては1人であったり5人であったりというのはありましたが、多くの期間が3人程で動いていました。