天の月

ソフトウェア開発をしていく上での悩み, 考えたこと, 学びを書いてきます(たまに関係ない雑記も)

各社から学ぶ!フロントエンドのためのリアーキテクチャに参加してきた

findy.connpass.com

こちらのイベントに参加してきたので、会の様子と感想を書いていこうと思います。

会の概要

以下、イベントページから引用です。

日々刷新されるソフトウェア開発において、自組織サービスの技術的な負債の蓄積は多くの企業が直面する重要な課題です。自社製品をより良いものにするため、質を担保するために「リプレイス」や「リファクタリング」という課題に、業界全体が取り組んでいます。

本イベントでは、技術的負債のフロントエンド部分に着目しました。自組織で技術的負債に向き合ってきた皆さんに登壇いただき、具体的な事例や実践的なアプローチを交えながら、直面した課題とその解決策について詳しくお話しいただきます。 フロント/サーバサイドエンジニアの方はもちろん、リプレイスを検討しているEMやPdMの方にとって、貴重な学びの場となる場を目指します。

会の様子

Storybook駆動開発でフロントエンドリアーキテクトに立ち向かう

Storybook開発で普段使っている機能

インタラクションを自動化するPlay Functionと、Storyの実行結果をテストするPortable Storiesの紹介がありました。

フロントエンドリアーキテクチャで抱えていた課題

事例のコンテキスト合わせとして、

  • 変更に時間がかかっていた
  • 可読性やテスト容易性、変更容易性やモダンフロントエンドとのGapが課題となっていた
  • 持続可能なコードベースを作りたかった
  • ページ/コンポーネント単位でリアーキテクトし、複合コンポーネント単位でStorybook駆動開発を実施することにした(Container/Presentationレイヤーに分けて開発をすることでPresentationレイヤーがUIの関心に集中できるようにした)

という説明がありました。

開発体制

8年間開発運用がされているシステムということもあって、画面数は180以上あるそうですが、領域を分けずに1つのIssueを一気通貫でエンジニアが担当することが多いという話が出ていました。

Storybook駆動開発の効果

テストコードを同時に実装する文化が醸成できたとともに、レビューやリファクタリングが簡単になったそうです。また、複合コンポーネント単位を採用することで漸進的にリアーキテクトができるようになったということでした。

一方で、開発を起動に乗せるために自分たちに合う実装方針やコンポーネント設計を模索したのはなかなか大変だったそうです。

Storybook駆動開発を起動に乗せるアプローチ

フロントエンドやバックエンドで分業していないため、StorybookのためだけにAPIモックコードを作るのはやりたくなかったということで、当初使っていたAPIモックコードを廃止したことが大きかったということです。

Pages Router × EmotionからApp Router × Vanilla-extractへの移行

App Routerとvanillaの導入に踏み切った背景

初期ロード時のパフォーマンス向上が見込まれるApp RouterのReact Server Componentsが魅力的だったという話がありました。

ただし、SSRに特化しておりRuntime時にCSSを生成するRuntime CSS-in-JSのようなクライアントサイドの処理はサポートしていないという問題があり、vanilla-extractを導入することにしたそうです。

vanilla-extractの主要な特徴

vanilla-extractは、

  • Build時のスタイル生成
  • 動的なテーマ設定が可能
  • TyoeScriptとの完全統合

が特徴としてあるという話がありました。

vanilla-extractとemotionの差異

実際のコードベースで、vanilla-extractとemotionの差異比較をしてくれました。

まず、ファイル定義とprops指定は、Emotion内では同一ファイル内でスタイル定義してpropsを直接使用するのに対して、vanilla-extractではスタイル定義は基本的に別ファイルで行うという話がありました。

次に、擬似クラスの指定に関してはEmotionでもvanilla-extractでも殆ど記述方法に差異はないという話がありました。

最後に、ファイル名に関してはvanilla-extractが.css.tsになるのに対してemotionでは.tsxになったそうです。

vanilla-extractを使ったことでよかったこと

社内アンケートでも、型を使えたことでコードの可読性や保守性が向上したという話が出ていました。

Nuxt.jsからNext.jsに乗り換えるにあたって大変だったこと

移行背景

Vue2がEOLになったのが主因だという話がありました。

Vue3へのアップデートも考えたそうですが、Vue2, Nuxt2, Vuetify2を同時にバージョンアップするコストの高さや他プロダクトでNext.jsを使っていたことからもフレームワーク移行の決定をしたそうです。

移行作業

1-6人で1年間くらいかけて予定通り移行したということでした。

移行で大変だったこと

まず、開発メンバーの習熟が大変だったということでした。
移行に参加していないメンバーがReactで開発を進められるように考える必要があったのが大変だったということで、一定の移行までは少人数でがっと力を入れて移行した後ペアプロなどで主要メンバーを増やし、(最後の移行最終段階では主要メンバーが別プロダクトに行ったこともあり)サポートメンバーが事前により慣れてもらうように工夫したそうです。

次に、Nuxtの際にページコンポーネントがグローバルステート的な形で状態保持していたそうです。
しかし、適切に各コンポーネントで状態保持できるようにした結果、タブを切り替えると状態が全て消えてしまうという事象が発生したそうです。
そのため、ユースケース単位でE2Eテストを確保したりといった工夫の必要性を痛感したそうです。

最後に、パフォーマンス低下があったそうです。
Next.jsに移行してからはSWRを使って適宜リバリデートを行うようにしたということですが、マウント時に必要なAPIを一度叩いていたNuxt時代と比較するとサーバーリクエストが大きく増加してしまったそうです。

フロントエンドリアーキテクチャの結果生じたワークフローの変化

実施したリアーキテクチャ内容

半年くらいでリアーキテクチャをしてからは17ヶ月くらい安定的に運用できているということです。
アーキテクチャの具体的な内容としては、

  • 実装におけるコード自動生成
  • Presentation層とContainer層の分離
  • 依存関係テスト
  • 名前空間テスト

をしたそうです。

アーキテクチャが必要な理由

本来リアーキテクチャは誰もやりたくないものであるという前提で、顧客にプロダクトを提供するまでの速度を最大化させるためにリアーキテクチャをしているんだという話がありました。

アーキテクチャによって変化したワークフロー

実装する際には、様々な決断をする必要があり、そこに時間がかかっているため、アーキテクチャやテストが決断のための最短経路を用意するのが重要だと考えているそうで、ワークフローの変更の際は決断を高速化するようなワークフロー改善のみ行ったということでした。

会全体を通した感想

発表してくれたみなさんが、技術の話にとどまらず事業にどういう形で紐づいているのか?というのを話してくれたのが非常に良かったです。

コードの可読性や保守性といったところにフォーカスしたリアーキテクチャの事例が多いなあとは思ったので、パフォーマンス向上といった別要因でのリアーキテクチャ事例に関しても今度聞いてみたいなと思いました。