はじめに
駅メモ!開発チームエンジニアの id:kaidan388 です。
駅メモ!のフロントエンドは Vue で書かれており、およそ 1500 コンポーネントあります。 Vue2 が EOL を迎えるに際して、これをどう Vue3 に移行するかが問題になりました。
具体的には以下の 2 点をどう達成するか、というのが問題になります。
- 普段の機能開発を止めずに、Vue3 移行を進めたい
- 普段のリリースを止めずに、Vue3 のリリースをしたい
駅メモ!開発チームでは、途中メンバーの交代もありつつですが、基本的に 3 名で 1 年半かけて、上の要件を満たしつつ Vue3 へ移行を完了しました。
この記事では、いかにして Vue3 化を完了したか解説しようと思います。 技術的な難しさについてはすでに多くのブログで語り尽くされているように思うので、ここでは、チームの運用やその他特別な工夫について語ります。
具体的には以下のような工夫を行いました。
- 差分を可能な限り小さくする
- スプレッドシートを用いた、作業の見積もり及び進捗の可視化
- 実装に詰まったらすぐに相談できる環境の用意
- Vue2/Vue3 緊急切り替えボタンの作成
移行に際しての問題点
まずは、移行開始時点で駅メモ!のフロントエンドがどのような状況にあり、移行に際して何が問題になったかを、簡単に整理します。
まずは、なんといっても、コンポーネントの多さが問題になりました。
フロントエンドの実装の大部分は Vue2 で書かれており、コンポーネント数は 1500 ほどありました。 この数の多さにより、以下の 3 点が問題として現れてきました。
- 作業工数が大きくなる
- 工数見積もりが難しい
- 移行作業の進捗管理が難しい
また、アプリの歴史の長さからくる、実装の読みづらさも移行作業の障壁でした。
元々駅メモ!のフロントエンドは Angular で書かれており、それを Vue2 に移行したという経緯があります。そのため、駅メモ!に初期からあるコア機能の実装は、Angular と互換を保つために、独自の実装が多く含まれています。Vue3 は破壊的変更が多く、この互換性のための実装がそのままではうまく動かないケースが多々ありました。 その他にも、10 年前と今とで設計思想が微妙に変わっていたり、初期の実装には社内で作った独自のフレームワークが使われていたりと、歴史の長さからくる実装の読みづらさは様々な場所で障壁として現れてきました。
いかにして普段の機能開発への影響を抑えるか、という点も問題になりました。
正確な見積もりではないにしても、1500 コンポーネントあることを考えると半年〜1 年以上は時間のかかるプロジェクトになるだろうというのは、駅メモ! 開発チーム内でも先にわかっていました。これほどの長期間駅メモ!の新機能開発を止めることは、当然できません。移行の実装から反映まで、Vue3 化に関わらない作業への影響を最低限に抑える方法を考えることも、問題になりました。
ここまでの問題を整理して、以下に箇条書きします。
- 作業工数が大きくなる
- 工数見積もり・進捗管理が難しい
- 古い実装が読みづらい
- 普段の開発への影響を最小限にしたい
これらの問題にどのように対応したか、このブログ記事で紹介していきます。
差分を可能な限り小さくする
作業工数の大きさに対応するため、移行時の差分は必要最低限にするという方針で作業を行いました。
話を始める前に、まずは、移行計画の変遷について説明させてください。
駅メモ!のフロントエンドは、Vue2 が使われていること以外にも様々な問題を抱えている状態でした。 例えば、全体的に使われているパッケージが古く、それらを更新する必要があります。他にも、ビルド時間が長い、ファイル構成がまちまちで統一感がない、など解決すべき課題は数多くあります。
それらを加味し、以下の記事で紹介した移行計画が立案され、これを実行しました。 tech.mobilefactory.jp
ただ、結論としては、必要な工数が現実的でないとわかったため、この方針は却下されることになります。
実際の作業時間について説明すると、まずは、作業の合間でいくらかの中断もあったのですが、パッケージを切り分けるなどの移行の下準備に半年かかりました。 その後、試しに駅メモ!のチュートリアル画面の移行を行ったのですが、60 コンポーネントの移行に 3 ヶ月ほどの時間を要してしまいました。これは、Vue3 移行と一緒に、sass を node-sass から dart-sass に置き換えようとしたことが主な要因で、css をほぼ全て書き直す必要が生まれたからです。
作業に慣れることでいくらかのスピードアップは期待できますが、流石に、60 コンポーネントに 3 ヶ月かかる見積もりでは、1500 コンポーネントの移行を完了することは現実的でなさそうです。
というわけで、一緒に解決したかったフロントエンドの様々な問題は一旦諦め、Vue2 を Vue3 に置き換えることだけに集中して作業を行う方針に決まりました。 具体的には、Vue3 のマイグレーションガイド通りに作業を行い、レガシーコードとの兼ね合いを考えるときも負債には目をつぶり可能な限り差分を小さくする、という方針です。
方針転換後は作業スピードも目に見えて向上しました。
プロジェクトが始まったのが 2023 年の 4 月ごろ、方針が変わったのが 2024 年の 3 月で、実際に Vue3 化が完了したのは同年 9 月の末になります。 つまり、チュートリアルの移行完了(諸々合わせると 80 コンポーネントあります)までに 1 年かかり、駅メモ!本体の 1500 コンポーネントの移行完了までに 7 ヶ月かかったことになります。
方針転換とはすなわち、過去 1 年分の進捗をなかったことにする決断なので、当時はかなり悩みました。ただ、体感として、方針変更後は作業完了の目処が立つようになり、ゴールが見えることで気持ち的にも楽に作業できるようになったように思います。 作業の見積もりや作業の計画の大事さを身をもって体験した業務だったと思います。
スプレッドシートを用いた、作業の見積もり及び進捗の可視化
工数見積もり・進捗管理の難しさに対応するため、Google スプレッドシートを用いて進捗の管理を行いました。
Vue3 化の作業は、締め切りは明確には決まっていませんでした。 これは、作業量の多さから正確な作業完了時期を考えることが難しく、締め切りを作っても守れるかどうかは未知数となるためです。
しかし、締め切りがないと、つい作業ペースが遅くなってしまい、Vue3 化の反映がいつまでもできなくなるのではないかという懸念があります。
その問題を解決するために使われたのが、Google スプレッドシートです。
下図は、実際に進捗管理で使っていたスプレッドシートです。
別のシートに、作業しなければ行けないコンポーネント名が 1500 列並んでいて、移行が終わって親ブランチにマージするタイミングでその別シートに完了のフラグと日付を記録するようにしていました。その作業により、上記のバーンアップグラフが描画されます。
今回の Vue3 プロジェクトでは、9/30 を作業完了の目安として理想の線を描画、そしてできるだけいつもその線を上回る状態を維持することを目指して作業を行いました。 途中でその想定より速度が出るとわかったので、1 日 14 コンポーネント作業することを目処に理想の線を引き直したりもしています。
また、Vue3 移行では週に 1 回のペースで振り返りを行いました。その振り返りでも、このグラフの傾きを一定にする、もしくは今より傾きを大きくするために、障壁になっているものは何かという視点で議論をしました。このブログで書いている工夫も、この振り返り会から生まれてきたものです。
目にみえる進捗があることで、チーム内はもちろん、チーム外に向けても進捗状況が共有しやすく、結果健全に作業を進められたのではないかと思います。
実装に詰まったらすぐに相談できる環境の用意
古い実装が読みづらい問題に対応するため、朝会の後にすぐ相談できる環境を用意していました。
前提として、モバイルファクトリーでの勤務はフルリモートになっています。 難しい実装にぶつかってうまく理解できなくなった場合は、まず Slack で声をかけ、誰かに Google Meet に参加してもらって相談する、という流れをとります。 普段はこの順序で問題は起きないのですが、Vue3 移行では古い実装を読むたび頻繁に行き詰まります。頻度も高いので声もかけづらく、相談がしづらい状況が生まれてしまいました。
これを解決するために、Vue3 移行チームでは、毎日の朝会の後お昼休みに入るまで、朝会の Google Meet の部屋に残ってもくもく会をしていました。 もくもく会とは、通話は繋いだまま基本的に黙って作業し、困ったことがあったら相談する、という会です。
これを行うことで、朝会の後少し雑談し、そしてそのままもくもく会で実装の行き詰まっている点を相談する、という流れを作ることができました。作業に行き詰まる時間も短くなり、進捗も上がるようになったと思います。 相談する側の心理としても、わざわざ声をかけて人を募るより朝会の後自然な流れで話す方が、些細な問題でも気軽に相談でき、相談しやすくなったように思います。
Vue2/Vue3 緊急切り替えボタンの作成
普段の開発への影響を最小限にするため、 Vue2/Vue3 緊急切り替えボタンを作成しました。
これは特に、反映時に、Vue3 以外の開発への影響を下げるための工夫です。
移行作業は、Vue3 移行のための親ブランチを作成して、そこから子ブランチを切り、ディレクトリ単位で進めました。 移行作業はその要領で普段の開発と並行して行えたのですが、問題は反映です。
Vue2 でも動く破壊的変更ではない差分は先に反映したりしたのですが、それでも最終的に 1300 ファイルほどに差分があるプルリクを反映する必要がありました。 また、反映は 3 日間で終える必要がありました。これは、反映期間中はできるだけ Vue3 以外のデプロイを止めて、不具合が起きてもすぐに対応できる状況を作ろうと、チーム内で相談した結果です。
これらを踏まえ、以下のような作戦で反映を行いました。
- サーバ上に、Vue3 の差分を含まないビルド成果物(以下 Vue2 ビルドと記述します)と、Vue3 の差分を含むビルド成果物(以下 Vue3 ビルドと記述します)の、両方を配置する
- Vue2 ビルドと Vue3 ビルドの成果物の切り替えは、管理画面の操作からデプロイなしで行える
- 3 日のうち、最初の 1 日で様子を見ながら Vue3 ビルドを受け取るユーザの割合を上げる。2 日目で 100%にする。3 日目は様子見と不具合対応
- 万が一クリティカルな不具合が出た場合、チームと相談しつつ、管理画面から Vue2 ビルドに切り替える
このうち特に便利だったのは、Vue2 ビルドと Vue3 ビルドの成果物の切り替えを管理画面からの操作でデプロイなしで行えるようにした点です。 これがあることで、もし、駅メモ!が遊べなくなるようなクリティカルな不具合を出したとしても、 5 分以内に切り戻せるので、心理的に安心して作業を進められました。
なお、実際には、この切り替え機能で Vue2 に戻すことはありませんでした。
反映時、軽微な表示の崩れは複数見つかりましたが、ゲーム体験にクリティカルに響くような不具合はなかったからです。これは、社内で 3 ヶ月ほどかけて入念に動作確認していたことと、どの程度の不具合であれば修正を後日に回してよいかをチーム内でよく握り合わせていた成果かと思います。
まとめと今後の展望
駅メモ!という 1500 コンポーネントある巨大な Vue2 アプリの Vue3 移行について、チーム運用やその他特別な工夫について話しました。
具体的には、以下の 4 点を紹介させていただきました
- 作業工数が大きくなってしまうので、差分を可能な限り小さくする
- 工数見積もり・進捗管理が難しいので、スプレッドシートを用いて作業の見積もり及び進捗の可視化をする
- 古い実装が読みづらいので、実装に詰まったらすぐに相談できる環境を用意する
- 普段の開発への影響を最小限にしたいので、Vue2/Vue3 緊急切り替えボタンを作成する
これらの工夫により、7 ヶ月ほどで、1500 コンポーネントある Vue2 アプリを Vue3 に移行完了することができました。
今度は、駅メモ!のフロントエンドのさらなる改善に努めたいです。 Vue3 化が終わったとはいえ、古いパッケージが使用されていたり、Angular と Vue の実装が混じり合っている部分があったりと、駅メモ!のフロントエンドには多く問題があります。
チーム内で行っている改善の仕組みを用いて、これらに取り組んでいきたいです。 tech.mobilefactory.jp
また、Vue3 化が終わって明確に良かった点として、駅メモ!のフロントエンドの全容を把握しているエンジニアがチーム内に生まれた、という点が挙げられます。
今まで、駅メモ!のフロントエンドは歴史の長さと実装の多さから、その全容を把握できるエンジニアがいない状況でした。結果、何か改善を入れようと思ってもそれで問題が生じないかの判断が難しく、踏ん切りがつかない場面が多々ありました。 今回の Vue3 化で、駅メモ!の実装の全体を把握しているエンジニアがチーム内に生まれ、結果改善の取り組みも進めやすくなったように思います。
エンジニアの生産効率性をさらに上げられるよう、今後も改善を継続したいです。