🌟

AIと進めるフロントエンドリプレイス

に公開

この記事は「Hacobell Developers Advent Calendar」ー 19日目の記事です。

はじめに

現在ハコベルの一部のプロダクトではVue.jsからReactへのフロントエンドリプレイスプロジェクトが進行中です。
リプレイスのプロジェクトは一般的にそれ自体が直接的な利益を生むわけではないため、ビジネス的な優先度はどうしても後回しになりがちです。
しかし、期間が延びれば延びるほど、新旧2つのコードベースを同時に保守する負担は増えていきます。(例えば既存のVueアプリへの機能追加は、同時にReactアプリでの新規実装も意味します。)
この「二重管理の期間」を短縮するためには開発速度の向上が急務であり、その手段としてAIの活用を検討しました。
この記事ではハコベルで実践し始めているその手法をご紹介します。

SDDベースのリプレイスワークフロー

開発速度向上を実現するためのアプローチとしては、チームで既に導入し、一定の成果を上げていた「SDD(Specification Driven Development: 仕様駆動開発)」を採用することにしました。
SDDとは、コードを書く前に「仕様書(ドキュメント)」を作成し、振る舞いやデータ構造を定義してから実装に移る手法です。
私たちのチームでは、これを導入することで「実装時の迷いが減る」「手戻りが最小化される」「属人性が排除される」といったメリットを享受していました。(※この記事ではSDDの詳細に立ち入りません。私たちのチームでのSDDの工夫は、後日記事が公開される予定なのでぜひそちらもご覧ください。)

リプレイス専用にカスタマイズされたSDD

はじめは通常の開発と同じようなSDDでフロントエンドリプレイスも行っていたのですが、以下のようにフロントエンドリプレイス特有のコンテキストに適応させる必要が出てきました。

既存コードこそが仕様である
通常の開発では「こんな機能が欲しい」という要望が起点ですが、リプレイスでは「今動いているVueの挙動」が基本的にはそのまま仕様になります。

膨大なドキュメント量
新規機能開発とは異なり、リプレイスは「すべての機能」を移行する必要があります。そのため、作成すべき仕様書の量は膨大になり、ドキュメントに何を書くべきかを精査する必要がありました。

アーキテクチャの再現性が命
リプレイスは技術的負債を解消する絶好の機会ですが、同時にこの段階で設計がブレれば即座に新たな技術的負債を生み出すというリスクを孕んでいます。

「Vueのコードを入力としてAIが仕様に逆コンパイルし、それをReactの統一された設計に変換する。」
この一連の流れをパイプライン化し、大量のファイルを安定して処理できる仕組みとして構築したのが、次に紹介するワークフローです。

ワークフローの全体像と構成

まず全体像の理解のために、プロジェクトの.claudeディレクトリのイメージをお見せします。
Claude Codeのコマンドを活用し、各ステップに対応するプロンプトやスクリプト、テンプレートを用意しています。(コマンド名のferはFrontEnd Replacementの略です)

/
└─ .claude
      ├─ commands
      │     ├─ fer-requirements.md  (Step 1: Vue解析 → 仕様書)
      │     ├─ fer-design.md        (Step 2: 仕様書 → React設計)
      │     ├─ fer-tasks.md         (Step 3: 設計 → 実装タスク)
      │     └─ ...
      ├─ skills
      │     ├─ vue-dependency-analizer (Step 0: 依存解析用)
      │     │     ├─ scripts
      │     │     │     └─ ...
      │     │     └─ SKILL.md
      │     └─ ...
      └─ templates
            ├─ fer-requirements.md
            ├─ fer-design.md
            ├─ fer-tasks.md
            └─ ...

対話と成果物の流れ

実際の開発では、上記のコマンド(テンプレート)をチャット上で順次呼び出し、AIと対話しながら進めていきます。

User:   /fer-requirements  (Vueファイルを解析して仕様書を作って)
Claude: (要件定義書案を出力...)
User:   (内容をレビュー・修正指示) --> OKなら requirements.md として保存

User:   /fer-design        (確定した仕様書をもとに設計して)
Claude: (設計書案を出力...)
User:   (内容をレビュー・修正指示) --> OKなら design.md として保存

User:   /fer-tasks         (設計をもとに実装タスクに分解して)
Claude: (タスク一覧を出力...)
User:   (内容をレビュー・修正指示) --> OKなら tasks.md として保存

このフローを経ることで、最終的にプロジェクトのリポジトリには以下のようなドキュメントが生成されます。

/
└─ docs
     └─ specs
          └─ PBI-1234 (Task ID)
               ├─ requirements.md  (Step 1の成果物:仕様)
               ├─ design.md        (Step 2の成果物:設計)
               └─ tasks.md         (Step 3の成果物:実装計画)
markdownの中身に興味がある方はこちらでチラ見せします
commands/fer-design.md
---
description: FER要件に基づく詳細設計仕様の作成
---
## 概要
このコマンドは、フロントエンドリプレイス(FER)の要件定義書に基づいて詳細設計を体系的に行うための指示書です。

使用方法:
/fer-design <ID>
/fer-design @docs/specs/<ID>/requirements.md

## コンテキスト
- 要件定義書: @docs/specs/<ID>/requirements.md
- テンプレート: @.claude/templates/fer-design.md

## あなたのタスク

### 1. 前提条件の確認
- `docs/specs/<ID>/requirements.md`が存在することを確認する

### 2. Vue実装の分析
移行対象のVueコンポーネントやロジックを分析し、以下を抽出する:
- 既存のVueコンポーネント構造
- 状態管理パターン
- 暗黙の要件やエッジケース

### 3. 設計書の作成
テンプレートに従って設計書を作成する。

**フロントエンド固有の考慮事項**:
- レイヤー構造(Screens/Features/UI/Repositories/Usecases)を遵守する
- コンポーネント設計では以下の層を明確にする:
  - Screens層: 画面全体の構成
  - Features層: 機能単位のコンポーネント(hooks, types含む)
  - UI層: 再利用可能なUIコンポーネント
...
templates/fer-design.md
# FER詳細設計書

> この設計書は Vue.js 版で実装済みの仕様を React で完全に再現することを目標とします。

## 1. アーキテクチャ概要

### 1.1 Vue版との構造対応

| Vue要素 | 参照(Few-shot) | React要素 | 設計意図 |
| ------- | ---------------- | --------- | -------- |
| `[Target.vue]` | `[Reference.tsx]` | `[NewTarget.tsx]` | レイアウト構造を参照 |
| `[data/methods]` | `[useReference]` | `[useNewTarget]` | フックの分割粒度を参照 |

## 2. コンポーネント設計

### 2.1 コンポーネント一覧

|| コンポーネント名 | 責務 | Vue版対応 |
| --- | ---------------- | ---- | ---------- |
| Screens | [ScreenName] | [責務] | [VuePage.vue] |
| Features | [FeatureName] | [責務] | [VueFeature.vue] |
...

こうして「何を作るか(仕様)」「どう作るか(設計)」が明確な状態を作ってから、初めてコーディングに入ります。 ここからは、具体的な各ステップ(Step 0〜3)について解説します。

Step 0:解析

一般的なSDDには存在しないステップですが、AIによる「実装漏れ」を防ぐために重要なフェーズです。
リプレイス対象のページに関連するすべてのファイルを洗い出すAgent Skill(vue-dependency-analizer)を使って、影響範囲を特定します。
このステップを経ることで、子コンポーネント、Mixin、外部ライブラリといった「隠れた依存」に後から気づいて絶望することを防ぎ、安心してタスクに着手できるようになります。

Step 1:要件定義

さきほど「既存コードこそが仕様である」と書きましたが、Vueのコンポーネントを機械的にReactコンポーネントに変換してはいけません。既存のアーキテクチャには技術的負債が含まれているからです。

しかし、すべてのコードを無視するわけにもいきません。既存コードの中には、ビジネスロジックや表現といった再利用すべき重要な「資産」も含まれているからです。私たちは、以下のようにコードを分別して扱っています。

  • 資産(そのまま移植したいもの):
    • 純粋なJavaScript/TypeScriptのロジック(ビジネスルール、計算式、バリデーション等)
    • HTMLやCSSなどのスタイリング
  • 負債(刷新すべきもの):
    • Vue固有の状態管理(data, computed)やライフサイクル(created, mounted)
    • MixinやGlobal Stateへの密結合

このフェーズでは、AIに対して「純粋なロジックやスタイルは『資産』として抽出しつつ、Vue固有の振る舞いについては一度抽象化して『仕様』として定義し直す」ようテンプレートで指示します。これにより、ビジネスロジックは維持したまま、実装パターンだけをモダンに刷新する準備が整います。

Step 2:設計

Step 1で抽出された「仕様」と「資産」をもとに、ここで初めて「Reactでの設計」を書きます。 AIに我々のアーキテクチャをコンテキストとして与え、Vueの1つのファイルが、Reactのどのファイル群に分割されるかという具体的な対応関係を定義させます。

このとき、すでにリプレイスが完了している既存のReactコンポーネントのコードがあれば、「実装の正解サンプル(Few-shot)」としてAIに参照させます。 いきなりコードを書き始めるのではなく、この設計をAIに出力させるプロセスを挟むことで、「実装時の迷い(このロジックはどこに書くべきか?)」を減らし、コードの品質を維持します。

Step 3:実装

設計が固まれば、それを実現するためのタスク一覧(tasks.md)を作成させます。 ここまでのステップで「仕様」と「設計」が明確になっているため、AIへの指示も「tasks.md の1番目のタスクを実装して」といったシンプルなものになります。

いきなり実装に入るのではなく、タスクレベルまで分解することで、AIが一度に抱えるコンテキスト量を制御し、実装ミスを防ぎながら着実にコーディングを進めることができます。

まとめ

今回ご紹介した「AI × SDD」によるリプレイスフローは、単にコードを書くスピードを上げるだけでなく、リプレイスプロジェクトにつきものの「精神的な負荷」を大きく軽減してくれました。

  • 認知的負荷の低減: 巨大なVueファイルを前に途方に暮れることがなくなり、「解析→要件→設計→実装」と小さなステップに着実に集中できる。
  • 品質の均一化: 誰が担当しても、AIというフィルタを通すことで、定義されたアーキテクチャに沿ったコードが出力される。
  • 資産の継承: ドメインロジックやデザインといった重要な資産を、漏らすことなく確実に新環境へ引き継げる。

「既存コードを読み解き、正しい設計に落とし込む」という一番カロリーの高い部分をAIとSDDで型化することで、エンジニアはより本質的な「設計の妥当性検証」や「UXの改善」に注力できるようになります。
同じようなリプレイス作業をしている方がいれば、ぜひ一度AIをパートナーにした「仕様駆動」のアプローチを試してみてください。

Hacobell Developers Blog

Discussion