Figma開発の壁を越える:AmplifyユーザーのためのCursor+MUI高速開発ガイド

Amplify+Figma開発、便利だけどこんな課題ありませんか?

こんにちは。株式会社トラストの岩波です。

Amplify+Figmaは強力なWEB開発手法ですが、運用上の課題に直面したことはありませんでしたか?

  • Figma運用の複雑さ: Amplify+Figma独自の設定(コンポーネントのオーバーライド設定やリスト化など)が必要で、学習コストがかかる。
  • デザインの属人性: Figmaでのデザインは個々のセンスに依存しがちで、チーム内での品質維持が難しい。
  • 反映時間の長さ: Figmaでの変更を実際のコードに反映させるのに時間がかかり(amplify pull )、トライ&エラーのサイクルが遅くなる。
  • Gen2との互換性: 最新のAmplify Gen2環境では、Gen1のようなFigma連携が対応不足で使いづらく、 保守性や開発効率の観点から現行のFigmaベースの開発フローは障壁となり得ます。

弊社でも、以前 こちらの記事 でご紹介したように、AWS Amplify StudioとFigmaの連携を活用し、開発効率化を図っています。

このアプローチは小規模プロジェクトでは効果的ですが、規模が拡大するにつれ、Figma運用の複雑さや変更反映のタイムラグといった課題に直面することもありました。ちょうどAmplify Gen2が登場し、より効率的で保守性の高い開発フローが求められる中、MUIのようなコンポーネントライブラリを直接活用して開発速度を向上させる案も浮上してきました。

こうした背景を踏まえ、まずは比較的小規模なプロジェクトで、Figmaベースの開発からMUIへの移行を試みました。

その移行作業において、Cursor (AIコーディングアシスタント) と、特にそのコンポーネントの豊富さから MUI (マテリアルUIライブラリ) という組み合わせが有効でした。

この記事では、私たちが実践したFigmaベースのコンポーネントからMUIコンポーネントへ、Cursorを活用しながら効率的かつ安全に移行するための具体的なコツや注意点をご紹介します。同様の課題を抱える皆さんのプロジェクトで、開発効率化のヒントとなれば幸いです。


補足:Cursorエディタについて

本記事では移行作業に Cursor を活用します。CursorはAIを深く統合したコードエディタで、コード生成やリファクタリング、デバッグ支援などを対話形式で行えるのが特徴です。

もちろん、ChatGPTやClaudeのようなWebベースの単体AIサービスでも、コード生成や修正の依頼は可能です。しかし、Cursorには以下のような利点があり、特に今回のコンポーネント移行のようなタスクで力を発揮してくれます。

  • エディタ統合: プロジェクトの参照、コードの編集、ファイル作成などがエディタ内で完結するため、作業がスムーズです。
  • コンテキスト参照 (@): Cursorのコンテキスト参照 (@) シンボルを使って、プロジェクト内のファイルやドキュメントを簡単にAIとの対話コンテキストに追加できます。これにより、AIが既存コードや仕様を正確に理解した上で、より精度の高いコードを生成しやすくなります。

とはいえ、基本的なコード生成の考え方やプロンプトの工夫などは、他のAIツールを使う場合でも応用可能です。この記事で紹介するCursorの活用法を参考に、皆さんが普段使っているツールでも試してみてください。


具体的な移行の3ステップ

ここからは、Cursorを活用した具体的な移行プロセスを3つのステップに分けて解説します。

ステップ1: 準備フェーズ – 業務理解が最重要!

意外に思われるかもしれませんが、技術的な作業に入る前に 最も重要なのは、移行対象となる画面や機能の「業務内容」を深く理解すること です。理由は以下の通りです。

  • 適切なコンポーネント設計のため: 単に見た目を再現するだけでなく、業務フローに沿った使いやすいUIを設計するには、その機能が「何のために」「どのように」使われるのかを知る必要があります。
  • Cursorへの的確な指示のため: 業務内容を正確にCursorへ伝えることで、より意図に沿ったコード生成が期待できます。曖昧な指示では、期待しないコードが出力され、手戻りが増える可能性があります。
  • 生成コードの評価のため: Cursorが生成したコードが、業務要件を満たしているか(例えば、特定の条件下でのみボタンを表示するなど)を正しく判断するには、業務知識が不可欠です。

今回は、該当プロジェクトが途中参加だったため、下記のような試みを実施して効率的に業務理解を深めました。

  • 業務関連ドキュメントを一箇所に集約しMarkdown形式に変換した上で、ビューワーで確認する(この変換作業や内容の確認にもCursorを活用すると効率的)。変換したドキュメントは、後のステップでCursorの @ 機能などでナレッジとして参照できるように整理しておく。
  • 必要であれば、担当者や実際にその機能を使うユーザーにヒアリングし、不明点は必ず確認・解消する

ステップ2: 実装フェーズ – 段階的かつ安全に進めるコツ

いよいよ実装です。ここでは、安全かつ効率的に移行を進めるための具体的なテクニックを紹介します。

①段階的な置き換え戦略

一度にすべてのコンポーネントを置き換えるのはリスクが高いため、画面や機能単位で段階的に 進めることを強く推奨します。

②並行開発を可能にする設計

既存のコンポーネント(Figmaベース)に影響を与えずに移行作業を進めるため、新しいMUIベースのコンポーネントは別ファイルとして作成 しましょう。

  • メリット:
    • 既存機能への影響を最小限に抑えられ、問題発生時にもとの状態に切り戻しやすい。
    • 他の開発者が既存機能を修正する場合でも、並行して作業を進めやすく、Gitのコンフリクトリスクも軽減できる。
ファイル命名規則の例:
src/components/
├── UserInputForm.tsx # ユーザー入力フォーム (Figma版) 
└── UserInputFormMui.tsx # ユーザー入力フォーム (MUI版)
  • 比較・検証をしやすくする工夫:
    • React Context などの状態管理ライブラリを使って、表示するコンポーネント(Figma版/MUI版)を切り替えるフラグを持たせます。
    • 開発環境用に、このフラグを切り替えるスイッチボタンなどを画面上に設置すると、新旧のUIを簡単に比較検証できて便利です。

③効果的なCursorへの指示方法

Cursorにコンポーネントの置き換えを依頼する際は、以下の点を意識すると精度が向上します。実際に、「このFigmaコンポーネントをMUIに変換して」といった単純な指示だけでは、元のFigmaファイルで対応できていた業務要件を満たさないコンポーネントが生成されてしまうことがありました。

  • 関連ファイルを コンテキスト参照 (@) で的確に含める:
    AIがコードを生成する上で必要な情報を過不足なく与えることが重要です。今回の移行作業では、以下のような関連ファイルを コンテキスト参照 (@) で含めることで、AIの理解度を高め、より精度の高いコード生成を引き出すことができました。
    • 置き換え対象の元コンポーネント : (@UserInputForm.tsx)
    • 型定義ファイル: コンポーネントが使用するデータの型情報 (@src/types/user.ts など)
    • 親子コンポーネント: Propsの受け渡しなど、インターフェースが関連するファイル (@UserRegistrationPage.tsx など)
    • 業務要件定義ファイル: ステップ1で整理した、機能の目的や仕様を記述したファイル (@UserInputForm_要件.md など)。Markdownが有効です。短い場合は直接プロンプトに記述してもOK。
  • 業務説明とファイルの役割を具体的に伝える:
    ステップ1で理解した業務内容に加え、@ で参照させたファイルがそれぞれ 何を 意味するのかを明確に伝えることが重要です。どのようなデータを扱い、どのような操作があり、どんなバリデーションが必要かなどを具体的に記述します。
@UserInputForm.tsx (Figmaベース) を参考に、MUIコンポーネントを使用して UserInputFormMui.tsx を作成してください。

参考情報
- データ型: @src/types/user.ts
- 親コンポーネント: @UserRegistrationPage.tsx

実装要件
- 以下のユーザー情報を登録・編集するフォームを作成してください
  - 名前 (必須、最大50文字)
  - メールアドレス (必須、メール形式チェック)
  - 年齢 (任意、数値のみ)
- 登録ボタンは、全ての必須項目が入力され、バリデーションエラーがない場合のみ活性化してください。
- 編集モードの場合、初期値がフォームに表示されるようにしてください。
  • 複雑なコンポーネントは分割して依頼:
    一つのコンポーネントが非常に大きい、または複数のサブコンポーネントで構成されている場合は、一度に全体を依頼するのではなく、より小さな単位に分割して依頼し、後で統合する方が成功しやすい場合があります。
    実際に、複数のサブコンポーネントで構成されたものを一度に生成させようとした結果、コードの一部が欠損してしまうケースがありました。

④実装時の注意点1: AI生成コードのレビューは必須

CursorのようなAIツールは強力ですが万能ではなく、特に複雑なロジックやプロジェクト固有の暗黙ルールを完全に理解してコード生成することは困難です。生成されたコードが常に最適で保守性が高いとは限りません。

また、後述する「段階的な改善とCursorとの対話」とも関連しますが、生成されたコードは最後にまとめてレビューするのではなく、意味のある単位(コンポーネントや関数など)で生成されるたびに、あるいは対話を通じて修正が加わるたびに、こまめに確認・レビューすることをお勧めします。

一度に大量のコードを確認するのは大変ですし、問題の発見が遅れる原因にもなります。

そのため、AIが生成したコードは必ず開発者自身がレビューし、最終的な品質と動作に責任を持つ必要があります。

意図しない動作、バグ、保守性を損なう実装(冗長なコード、不適切な命名、ロジックの重複など)がないかを確認しましょう。このレビューは、AI支援開発において最も重要なプロセスの一つです。

※CursorのRules for AI機能である程度方針を予め伝えることも可能です。この辺りはどこかで触れられたらと思います。

⑤実装時の注意点2: TypeScriptの型定義方針

TypeScriptプロジェクトの場合、型定義をどう扱うか方針を最初に決めておく ことが非常に重要です。

  • 方針1: 最初から型セーフを目指す (推奨)
    • メリット: コードの堅牢性が高まり、リファクタリングや長期的な保守が容易になる。予期せぬ実行時エラーを減らせる。
    • デメリット: 初期の実装に時間がかかる場合がある。型の整合性を取るためにCursorとのやり取りが増える可能性がある。
    • おすすめケース: プロジェクト初期、時間に比較的余裕がある場合、品質を重視する場合。
  • 方針2: 一旦 any 型で進める (非推奨、ただし状況による)
    • メリット: とにかく早く動くものを作りたい場合に、一時的な手段として実装速度を上げられる場合がある。
    • デメリット: 型チェックの恩恵を受けられず、実行時エラーやビルドエラーが多発しやすくなる。後から型を付けようとすると、かえって多大なコストがかかる。
    • 注意: この方針を取る場合でも、interface だけは定義し、プロパティを any にするなど、後で型を付けやすくする工夫は最低限行いたいところです。

特に、途中から場当たり的に型を付け始めると、型の整合性を取るのが非常に困難になり、コードが複雑化し、ビルド時に大量のエラーが発生する原因になりがちです。ローカル環境では動いても、CI/CDパイプラインでのビルドが通らない、といった事態も頻発します。

可能であれば、最初から型セーフな実装を目指すことを強くお勧めします。

⑥モックデータを活用したUI再現

初期段階では、バックエンドとの連携を一旦切り離し、UIの見た目と基本的な動作の再現に集中 するのが効率的です。

  • Cursorには、まずは固定のモックデータを使ってコンポーネントを実装するように指示します。
  • できればバックエンド連携は後回しにし、まずは画面デザイン(レイアウト、コンポーネントの種類、表示項目など)の認識合わせを優先します。

⑦段階的な改善とCursorとの対話

Cursorが生成したコードが、最初から完璧であるとは限りません。

  • 基本的な構造や方向性が合っていれば、まずは適用します。リセットしてやり直すより効率が良いです。
  • その後、具体的な問題点や修正したい点を指摘し、対話を通じて段階的にコードを改善していきます。
ありがとう。概ね期待通りですが、いくつか修正をお願いします。

1.  「登録ボタン」の活性化条件が間違っています。
    - 現状: 名前が入力されていれば活性化
    - 期待: 名前とメールアドレスの両方が入力され、メールアドレスの形式が正しい場合のみ活性化
2.  年齢入力フィールドで、数値以外の入力ができてしまいます。数値のみ受け付けるようにしてください。
3.  エラーメッセージの表示位置を、各入力フィールドの下に配置してください。

⑧UIの洗練

基本的な機能と動作が実装できたら、最後にMUIの機能を活用してUIの細部を調整し、見栄えや使い勝手を向上させます。

ありがとう。機能はほぼ完成しました。最後にUIを調整します。

- フォーム全体の左右パディングを `theme.spacing(2)` に設定してください。
- 「登録ボタン」をフォームの右下に配置してください。MUIの `Box` と `display: flex`, `justifyContent: flex-end` を使うと良いでしょう。
- ボタンの色をプライマリカラーに変更してください。
- 各入力フィールドの上に、説明ラベルを追加してください (`Typography` コンポーネントを使用)。

ステップ3: 検証・統合フェーズ

UIコンポーネントが完成したら、最終的な検証と統合を行います。

  1. バックエンド連携: モックデータを使っていた部分を、実際のバックエンド呼び出しに置き換えます。
  2. 動作検証: 実際のデータを使って、登録、編集、削除などの機能が正しく動作するかテストします。
  3. 最終的な置き換え: 新旧コンポーネントの切り替えフラグを削除し、MUIベースのコンポーネント (UserInputFormMui.tsx) を正式なコンポーネントとしてアプリケーションに組み込みます。
  4. 旧コンポーネントの削除: すべての検証が完了し、問題がないことを確認できたら、不要になった元のFigmaベースのコンポーネントファイルと関連コードを削除します。

移行を成功させるためのポイント

最後に、これまでの経験から得られた、移行プロジェクトを成功させるための重要なポイントをまとめます。

  • 業務知識を最優先に: 何度も強調しますが業務理解が重要でした。不明な点は必ず関係者に確認しないと品質の低下やデグレに繋がります。
  • 完璧主義を避ける: 最初から100点満点を目指す必要はありません。まずは動くものを作り、段階的に改善していくアプローチを取りましょう。
  • ユーザー体験を常に意識: 技術的な置き換え作業に没頭するあまり、最終的なユーザーにとっての使いやすさを見失わないようにしましょう。一方、ユーザビリティを重視したコンポーネントにリファクタリングする機会でもあります。
  • 開発者によるレビューは必須: Cursorは強力なツールですが、生成されたコードが常に最適とは限りません。必ず開発者がコードレビューを行い、意図しない動作や、保守性を損なうようなコード(例: 存在しないプロパティへのアクセス、過度に具体的な実装、共通化すべきロジックの重複など)が含まれていないかを確認しましょう。AIが生成したコードであっても、その品質に責任を持つのは開発者です。

まとめ:CursorとMUIで開発を加速しよう!

Figmaベースのコンポーネント開発が抱える課題に対し、CursorとMUIを活用した移行は有効な解決策となり得ます。

計画的かつ段階的に進め、業務理解を深め、Cursorとの対話を重ねることで、リスクを抑えながら効率的に、そしてより高品質で保守性の高いUIコンポーネントを構築できるでしょう。

この記事で紹介したアプローチや注意点が、皆さんのプロジェクトにおける開発効率化やUI品質向上のための一助となれば幸いです。ぜひ、CursorとMUIを活用した新しい開発スタイルを試してみてはいかがでしょうか?