- **役割:** フロントエンドエンジニア
- **体制:** フロントエンドエンジニア 5名 / バックエンドエンジニア 2名 / デザイナー 1名 / QAエンジニア 1名
- **技術スタック:** HTML, CSS, TypeScript / Next.js, React / Turborepo, GraphQL, urql, CSS Modules, Radix UI, eslint-plugin-jsx-a11y, Markuplint, @axe-core/playwright, SonarQube
**【概要・背景】**
既存の経費精算システムからフロントエンドを独立させ、技術的負債を解消する新規プロダクトの開発を担当しました。本システムは誕生から約6年が経過しており、Railsに依存したCoffeeScriptによる実装や不十分なテストによる目視での動作確認、バックエンドとの密結合など、技術的負債が蓄積している状況でした。これが開発者のモチベーションを低下させるだけでなく、採用においても「技術がレガシーで成長できるか不安」という懸念から内定辞退の要因となるなど、全社的な課題となっていました。この状況を打破するため、新規リポジトリを作成し、Next.jsとTypeScriptを用いたモダンなフロントエンド環境を立ち上げ、画面ごとに段階的なリプレイスを実施しました。
**【自身の役割】**
機能開発における詳細設計、実装、テスト、コードレビュー、QA対応、およびデザイナーとの仕様調整を一貫して担当しました。また、自身の強みであるアクセシビリティやスタイリングに関する知見をチームへ積極的に共有し、レビューを通じてチーム全体のコード品質向上と最適なUI実装を牽引しました。
**【発揮したバリュー・成果】**
**大規模リプレイスにおけるスコープ調整とステークホルダーとの合意形成:**
本プロジェクトにおいて最も苦労したのは、開発と並行して発生する「スコープの調整」でした。当時、デザインシステムの導入やインフラのAWS移行など全社的なプロジェクトが複数同時進行しており、想定外の連携作業が発生していました。さらにビジネス側からは、「リプレイスのついでにレイアウトを大きく変えたい」「既存の仕様ごと作り直したい」という要望も寄せられました。
しかし、社内でもほとんど前例のない大規模リプレイスにおいて、仕様変更まで同時に行ってしまうと、バグ発生時の原因特定が極めて困難になります。そこで私はチームとしてステークホルダーに対し、「Next.jsへの移行さえ完了すれば、そうした機能改善もより素早く行えるようになるため、まずは既存仕様の再現に集中させてほしい」というロードマップを提示し、丁寧に交渉を行いました。そうしてリプレイスにおけるスコープについて、他チームやビジネスサイドとうまく合意形成を図りながら、無事にモダンな環境へのリプレイスとリリースを達成することができました。
**Radix UIの技術選定:**
UIコンポーネントライブラリの選定において、Ant Design、Radix UI、React Ariaの3つを比較検証し、最終的にRadix UIを採用しました。
当初は社内実績があるAnt Designも有力な候補でしたが、リプレイスと並行して構築中であった経費精算システム独自のデザインシステムを適用するためには、ライブラリが持つ既存のスタイルをオーバーライドしていく必要があり、将来的なメンテナンスに懸念がありました。そのため、UIの振る舞いのみを提供し、スタイリングは実装側でコントロールできるヘッドレスUIからの選定としました。
次に、WAI-ARIAに準拠したヘッドレスUIであるReact AriaとRadix UIを比較しました。当時のReact Ariaは、状態管理フック(@react-stately)とDOMへのバインディング(@react-aria)を手動で行う必要があり、実装コストが高いという課題がありました(※当時はまだreact-aria-componentsはメジャーリリース前だったため検討対象に含めませんでした)。対してRadix UIは、Compound Componentパターン(Dialog.RootやDialog.Triggerなど)を採用していて、通常のHTMLに近い直感的なツリー構造でマークアップできるという利点がありました。
この「実装の容易さ」「コードの可読性」を評価してRadix UIを採用し、結果として独自のUIデザインで定義されたデザインシステムを、高いアクセシビリティと優れた開発体験を両立して構築することができました。
**品質とアクセシビリティを継続的に改善する仕組みづくり:**
開発者のスキルに依存せず品質を担保する仕組みとして、静的解析ツールの eslint-plugin-jsx-a11y や Markuplint を導入しました。さらに、カラーコントラストなどコードベースだけでは判定が難しい視覚的なアクセシビリティ要件の検証を自動化するため、@axe-core/playwright を用いたテストを実装しました。また、静的コード解析ツールである SonarQube を導入し、テストカバレッジなどの品質指標を可視化・測定できる体制を整えました。
単にツールを導入するだけでなく、これらのテスト結果やカバレッジをチームで確認・吟味する定例会を週に一度設けました。対応が必要だと判断したものは実装チケットとして起票し、通常のスプリントに組み込む運用フローを構築しました。この仕組みにより、機能開発が進むにつれて後回しになりがちな技術的負債の解消や品質向上といったプロジェクトメンテナンスを、開発プロセスの一部として継続的に実行することができました。
**【執筆記事】**
技術書典マーケットでの「Money Forward TechBook #8」にて、本分離プロジェクトで行ったアクセシビリティ改善活動について「アクセシブルなプロダクトを提供するための取り組み」という題目で執筆しました。その他プロジェクト関連の執筆記事は以下の通りです。
- [aria-labelで始める、アクセシビリティ改善活動](https://zenn.dev/moneyforward/articles/b5c9b060cf9237)
- [marginではなく、レイアウトを指定しよう(レイアウト手法 Stack、Clusterの紹介)](https://zenn.dev/moneyforward/articles/075a74334ca512)
- [画像が「情報」を持っているかどうかの判断基準、持っていない場合はalt=""を指定しよう](https://zenn.dev/moneyforward/articles/bc93f64ba4d36a)
- [href="#"のみの指定はやめよう(フォーカス移動の問題点)](https://zenn.dev/moneyforward/articles/18c45ef93815dd)