なんだだかんだでキレイにいかないFigmaのコード出力
ROXXではAIエージェントによるプログラミングを推進しています。その中で私がぶつかった課題はフロントエンドのソースコード生成自動化がいまいち上手くいかないということでした。
figmaのMCP接続でキレイなコードがパッと出力されれば良いのですが、下記のような問題に直面していました。
- 一応デザイン通りに出たはけどそのまま使える感じじゃない
- 結局その後の直しや繋ぎ込みでそれなりに時間使ってたりする
- 気づいたらキレイにしきれてないコードがたくさん積み上がっている
- MCP接続からのコード出力をどうコントロールしたら良いかがよく分からない
キレイにせずに入れるわけにも行かないし、直近の自分のタスクも短時間で終わらせないといけないので、とりあえずfigmaのプラグインで生成したコードをAgentで整形させるという手段を取っていたのですが、Agentとのフィードバックループで案外と汎用的に使える感じになってきてたので、今回はその指示ファイルを紹介します。
特に工夫したポイントは自動出力後が使いやすいコードを生成することなので、その点はfigmaのMCPを使いこなしている方も使える内容となっております。また、部分利用もしやすい内容かと思います。
対応スコープはfigmaファイル→整理された処理なしコンポーネント群の生成までです。
コンポーネント周りの技術スタックはReact / Tailwind / shadcnです。
使用方法(cursorの場合)
以下はcursorでの使用方法ですが、ClaudeCodeの場合でもcommandsなどで同様の運用できると思います。
- 事前準備
.cursor/rulesにプレースホルダーを記入したrulesファイルを配置
- コード生成
- figmaでコード生成したい要素全体をFigma to Codeのプラグインで出力
- 出力コードのルートにしたいReactファイルを追加しマークアップ部分に全文貼り付け
- 呼び出したいコンポーネントの指示をコメントで書き込み
- 下記のプロンプトでAgentを動かす
@{rulesファイル}の通りにfigmaから自動生成された{生成したReactファイル}のコードをプロダクションで使用するコードに変換してください
以下、テンプレート全文です。プロジェクトに合わせる部分はプレースホルダーにしてあるので書き換えてご利用ください。
--- description: figmaから自動生成されたコードをプロダクションで使用するコードに変換する処理のルールです globs: alwaysApply: false --- このルールを読み込んだら、「ルール:figma-convert.mdcを参照しました」と表示してください。 技術スタック: - {プロジェクトに合わせて記載。各バージョンを記載してReact/Tailwind/shadcn/Typescriptなど記載} コーディング規約は以下のファイルで管理されています。各ファイルを読み込んでプロジェクトの設定や規約を把握してください:: - {package.json, eslint.config, tsconfigなどのパスを記載} コード生成時は以下のルールに従ってください: 1. コンポーネント名はPascalCaseを使用 2. 関数名と変数名はcamelCaseを使用 3. 定数はUPPER_SNAKE_CASEを使用 4. 型定義は適切にエクスポート 5. エラーハンドリングは適切に行う # 概要 - HTML構造は変更せず、命名やファイル分割のみ行います - コンポーネントライブラリ内のファイル(`@{コンポーネントライブラリのパス}` 配下など)は変更しません # ステップ1: スタイリングを修正 - スタイリングはclassNameを使って整理してください - まずは、実際のレンダリング結果に影響しないスタイルを削除してください - 具体例: - CSSの仕様上、デフォルト値と同じスタイル(親要素のスタイルに依存する場合は、親要素のスタイルを確認) - 親要素から継承されるスタイルで、子要素に同じ値が指定されている場合 - 親要素のスタイルに依存するプロパティで、親要素がそのスタイルを持たない場合 - 同じプロパティが複数回指定されている場合の前者のプロパティ - 判断が難しい場合は、削除を行わずそのまま残してください - 共通定義のCSSは下記に配置してあるので必ず読んでください - @{共通CSSの配置場所} - 共通定義のCSSに定義されているのと同じ値のスタイルなどがある場合、共通定義のCSSを使用するようにしてください。 - クラス名やインラインスタイルの値が一致する場合は同じと見なします - 意味的に同じスタイルは同じと見なします(例:`16px` = `1rem`, `#3b82f6` = `rgb(59, 130, 246)`, `px-4` = `padding-left: 1rem; padding-right: 1rem;`) - TailwindのCSSクラスの記載は実際のCSS値が意味的に同じになりそうかで判断します - 判断が難しい場合は差し替えません # ステップ2: コンポーネントライブラリへの差し替え Figmaから自動生成されたコード内に、コンポーネントライブラリの使用を指示するコメントがある場合は、そのコメントに従って差し替えてください。 - Figma生成コード内に部品の使用を指示するコメントがある場合は、そのコメントを参照してください - 部品を使用する場合の例:`<!-- @/components/ui/Button -->` のようなコメントがある場合は、その指示に従って指定されたコンポーネントライブラリを使用してください - 部品を使用しない場合の例:`<!-- この要素は共通パーツを使用しない -->` のようなコメントがある場合は、部品を使わずに実装してください - コメントで指定されたコンポーネントライブラリのディレクトリ(例:`@{コンポーネントライブラリのパス}`)を確認し、利用可能なコンポーネントを把握してください - 差し替えの際は、以下の点に注意してください: - 元のスタイリング(`className`)を適切にコンポーネントのpropsに変換する - コンポーネントのAPIを確認し、正しいprops名を使用する - 必須のプロパティにはサンプルの変数を渡す - コンポーネントライブラリに該当する機能がない場合や、コメントで部品を使用しないと指示されている場合は、そのまま残してください # ステップ3: 変数の整理 - コンポーネントに渡されている値や埋められている文字は全てローカル変数として定義してください - 同一の構造が繰り返し使われている場合は配列の変数を渡したmap展開などに書き換えてください - 変数定義が終わったら変数を重複のないように正規化する整理をしてください - 変数の整理においては、React公式ドキュメントの「React の流儀」(Thinking in React)の原則に基づいて実施してください - 参考:@https://ja.react.dev/learn/thinking-in-react # ステップ4: state定義とコンポーネント分割 - React公式ドキュメントの「React の流儀」の原則に基づいて、stateを管理するべき階層を明らかにし、それに基づいたコンポーネント分割を実施してください。 - 管理するStateの内容と表示する内容に基づいてファイルをパスカルケースで命名してください - ディレクトリ構成は `@{コンポーネント配置パス}` の階層のように、呼び出されるコンポーネントが下階層に入っていくコンポーネントのコロケーションパターンでコンポーネント配置してください。コンポーネントと同名のディレクトリを作成してtsxファイルを配置するようにしてください。 # ステップ5: lintなど修正 - 静的解析エラーや警告が出ている箇所は修正してください。 - 特に下記のルールに気を付けてください {対応しきれないパターンなどがあったらコード例などを記載する}
指示テンプレート解説
部分的に使ったりもできるように、各記載の要点を解説していきます
ステップ1: スタイリングを修正
- まずは、実際のレンダリング結果に影響しないスタイルを削除してください - 具体例: - CSSの仕様上、デフォルト値と同じスタイル(親要素のスタイルに依存する場合は、親要素のスタイルを確認) - 親要素から継承されるスタイルで、子要素に同じ値が指定されている場合 - 親要素のスタイルに依存するプロパティで、親要素がそのスタイルを持たない場合 - 同じプロパティが複数回指定されている場合の前者のプロパティ - 判断が難しい場合は、削除を行わずそのまま残してください
プラグインから出したFigma自動生成のコードでは無駄なスタイリングを書かれることがけっこう多いと思いますが、こちらの記載で概ね対応ができました。
共通スタイルへの差し替えは環境によってルール調整して頂けたらと思います。
ステップ2: コンポーネントライブラリへの差し替え
実際にはほどんどの現場で部品レベルのコンポーネントが定義されていてそれを呼び出すような実装になると思います。
こちらは自動化の難易度が最も高いポイントだったので、この記事では下記のようにコンポーネント使用指示を入れることですぐに使える内容にしてあります。
- Figma生成コード内に部品の使用を指示するコメントがある場合は、そのコメントを参照してください - 部品を使用する場合の例:`<!-- @/components/ui/Button -->` のようなコメントがある場合は、その指示に従って指定されたコンポーネントライブラリを使用してください - 部品を使用しない場合の例:`<!-- この要素は共通パーツを使用しない -->` のようなコメントがある場合は、部品を使わずに実装してください
使用指示を記入する手数がかかりますが、これでも自分でコードを書くよりだいぶマシな工数で確実な対応が可能です。
弊社の場合、大きなプロジェクトではfigmaとソースコードで命名を統一したデザインシステムを整備しているので、実際にはその命名ベースで差し替えを指示しています。デザインシステムが整備されている環境ではこういった差し替えルールを定義することでこのステップも自動化可能になります。
デザインシステム整備までされてなくとも、Figma上のComponentのスタイリングとソースコード上の部品コンポーネントのスタイルが一致していれば、その一致を差し替え判断に使うこともできます。どのスタイルならどれのコンポーネントを使うかのルールをAgentに作成させておくなどである程度行けたりもします。
ステップ3: 変数の整理のセクション
その後が使いやすいコードを生成する上で最も重要なポイントとなります。
- コンポーネントに渡されている値や埋められている文字は全てローカル変数として定義してください - 同一の構造が繰り返し使われている場合は配列の変数を渡したmap展開などに書き換えてください - 変数定義が終わったら変数を重複のないように正規化する整理をしてください
この指示によって、作成されたコードの表示内容は整理されたベタ書きの変数を参照する形で出力されます。その変数をテストケースとしてロジックを書いたり、APIからの取得データに差し替えたりするなどスムーズに続きの作業に入ることができます。
と言っても分かりづらいと思うので実際に過去出力した具体例を紹介します。
こちらが自動出力→整形したコードの抜粋です
import { HiChevronRight } from 'react-icons/hi' type Prefecture = { name: string subText?: string } type PrefectureGroup = { title: string prefectures: Prefecture[] } const prefectureGroups: PrefectureGroup[] = [ { title: '北海道・東北', prefectures: [ { name: '北海道' }, { name: '宮城県' }, { name: '青森県' }, { name: '岩手県' }, { name: '秋田県' }, { name: '山形県' }, { name: '福島県' }, ], }, { title: '関東', prefectures: [ { name: '東京都' }, { name: '神奈川県', subText: 'JR京浜東北・根岸線(北浦和駅、浦和駅、南浦和駅、西川口駅、川口駅)' }, { name: '埼玉県' }, { name: '千葉県' }, { name: '茨城県' }, { name: '栃木県' }, { name: '群馬県' }, ], }, ] const PrefectureGroupSection = ({ group }: { group: PrefectureGroup }) => { return ( <div className="flex flex-col w-[390px]"> <div className="h-8 px-4 py-2 bg-text-secondary flex items-center"> <div className="text-text-invert-primary text-[--text-body-md] font-semibold"> {group.title} </div> </div> {group.prefectures.map((prefecture) => ( <PrefectureItem key={prefecture.name} prefecture={prefecture} /> ))} </div> ) }
ただ地方と都道府県と路線情報が書かれていたfigmaデザインから、適切に型定義のされた変数が生成・参照されていると思います。 フロントエンドでテストファーストなコーディングが可能な環境が整っている場合、そちらのAIプログラミングとも相性が良いです。
- 変数の整理においては、React公式ドキュメントの「React の流儀」(Thinking in React)の原則に基づいて実施してください - 参考:@https://ja.react.dev/learn/thinking-in-react
cursorエージェントはタスク中にWebを開くことができませんが、「Reactの流儀」のページの記載内容はClaudeやChatGPTに学習されているので、変数の整理はこのプラクティスに則った内容となります。
ステップ4: state定義とコンポーネント分割のセクション
先のセクションでReact公式のプラクティスに則った変数の整理をしていました。コンポーネント分割もそれに則った分割をする指示をすることで、React原理主義的に適切なコンポーネント分割となります。
コンポーネントを分割した際の配置方法はプロジェクトによって調整して頂けたらと思います。
ステップ5: lintなど修正のセクション
対応しきれずに同じようなエラーが出ることがあったので、そういったケースがあり次第Agentに追記させることで対応していました。
Figma関連の注意点
コード出力プラグインはFigma to Codeがおすすめ
コード出力プラグインはAIを使って生成するものなど色々ありますが、Figma to Codeがおすすめです。こちらは冗長なコードが出されて使いにくい印象をお持ちの方もいらっしゃると思いますが、出力が一番機械的なので、AI整形前提の場合は最もコントロールがしやすかったです。
AutoLayout漏れはなくす
Figmaファイル側でうっかりAutoLayoutが漏れてると、プラグインのコード出力時に実際の要素構造と違うコードが出力されてしまいます。Draftにコピーして修正などできると思いますが、デザイナー側にAutoLayout漏れは無くして置いて欲しい旨を伝えておけるとスムーズです。レイアウト設計的にwidth 100%のはずだけどpxで指定になってる、などの設定漏れなどについても同様です。
