Vue SFC と AI 駆動開発の相性が良い理由
はじめに
この記事では、私が最近試して手応えを感じている、カスタムブロックを用いた「Vue だからこそ実現できる」AI 開発のアプローチについて紹介します。
Vue SFC と AI 駆動開発の相性の良さについて興味を持って頂けたら幸いです!
既存の開発に「仕様駆動開発」を持ち込む難しさ
最近、AI 駆動開発の精度を高める鍵として「仕様駆動開発(Spec-Driven Development)」が注目されています。プロンプトに左右される Vibe Coding と比べると AI の出力のアウトプットが向上します。
しかし、このアプローチを導入するためには、大きく2つのハードルがあると感じています。
1つは、仕様を正確に言語化する難しさです。コードを書く前に仕様を正確に言語化するという開発スタイルは、実際にコードを書いていくことで要件を明確にするようなボトムアップのスタイルとは真逆であり、この進め方の違いに上手く馴染めていないという方も多いのではないでしょうか。
Spec Kit や Kiro といった専用の支援ツールも、必ずしもこの問題を解決してはくれません。ツールが提供するのは「仕様を記述する文法」であり、「何をどこまで仕様として書くか」という難しさは解消してくれません。
もう1つは、仕様とコードの分離が常に上手くいくとは限らないことです。例えば Spec Kit や Kiro を使った仕様駆動開発では、 *.spec.md や tasks.md のような別ファイルに仕様を定義して、それを AI に参照させることになります。Coding Agent などでは GitHub issue に書く場合も多いでしょう。
しかし、AI のコンテキストは有限かつ暗黙的なので、別ファイルや別サービスにある仕様書は、何度か指示を繰り返すうちにAIのコンテキストから抜け落ちてしまうことがあります。
さらに、これらのツールが採用する、「最初に仕様を定義し、それに基づいてコードを一括で生成する」というアプローチは、新規プロジェクトの立ち上げや、明確に切り出された機能の初期実装では非常に強力ですが、継続的な修正やリファクタリングにはあまり向いていません。
仕様を少し変更するたびに、再度 AI に全体を生成させるのは非効率であり、かといって直接コードを修正すれば、元の仕様書はすぐに過去のものとなってしまいます。これは、継続的にサービスを改善していくアジャイルな開発フローには適さない場合があります。
結果として、仕様駆動開発のメリットは理解しつつも、「ハードルが高くてついていけない」「思ったほど効果を得られない」「既存のプロジェクトとは嚙み合わない」などと悩んでいる方も多いのではないでしょうか。
Vue の <spec> ブロックの使い方
この2つの問題を同時に解決する手段として今回紹介するのが、Vue のカスタムブロックとして <spec> ブロックを追加し、そこに仕様を書き込む、というものです。
例えば、特定の要素を明るくハイライトし、その要素以外の画面全体を暗くする「スポットライト」的なコンポーネントを作りたい場合、まず以下のような <spec> だけを書きます。
<spec lang="md">
## slot で囲まれた部分だけを残して、それ以外を覆って暗くするスクリーンを表示します。
- モーダルダイアログの背景などに利用します。
- スクリーンの背景色は `rgba(0,0,0,0.3)` です。
- スクリーンはその位置を囲むように `<teleport>` タグを通して body 直下に配置されます。
- スクリーンは svg path で描画されます。
</spec>
あとは、AI に 「<spec> ブロックに従って app/components/SpotlightOverlay.vue を実装してください」と指示を出せば、仕様通りの実装が行われます。

<spec> ブロックが解決する問題
では、仕様を <spec> ブロックに書くというアプローチは、前述した問題を、具体的にどう解決するのでしょうか。
仕様の言語化を助ける「コンポーネント単位」の考え方
まず、<spec> ブロックに仕様を書くことで、開発者は仕様を適切な粒度で組み立てやすくなります。
冒頭でも述べたように、「コードを書く前に仕様を正確に言語化する」のはハードルが高いです。
しかし、<spec> ブロックを書くフローでは、開発者はまず「どのコンポーネントを作るか」を決め、その後に「このコンポーネントの責務は何か」を考える、という2つのステップに分かれるので、記述すべき仕様を整理しやすくなり、しかもコンポーネント分割の設計を AI に委ねずに済みます。
この「コンポーネント」という単位は、仕様を記述する粒度としても絶妙で、 props/emit/defineModel といったインターフェースの詳細や、「実装は SVG で行う」といった具体的な実装方針は、Kiro のような機能単位の仕様書に書くには細かすぎますが、コンポーネントのローカルな仕様として <spec> ブロックに記述するのは全く不自然ではありません。
コンポーネントごとであれば細かく記述しても 1ファイルあたりの仕様(指示)が長くなりすぎず、人間が書くのに適切な情報量を保てます。逆に、「 <spec> ブロックが長すぎる」と感じたら、それは「このコンポーネントの責務が多すぎる(=コンポーネントを分割すべき)」というサインです。
AIと人間の両方に優しい「仕様のコロケーション」
ファイルに直接仕様を書くのは、AI 開発におけるコンテキストの不安定さを軽減するメリットもあります。
多くの AI 開発ツールは、現在アクティブなファイルのコンテキストを最優先で参照するので、仕様とコードが同じファイルにあれば、 <spec> ブロックの内容は確実にAIのコンテキストに含まれます。これは「対話や作業が長くなると仕様がコンテキストから欠落する」という問題を防いでくれるので、AI のアウトプットの精度を大きく向上させます。
さらに、仕様とコードが同一ファイルで Git 管理されるのは、人間にとっても有益です。ファイルを修正する時に仕様も必ず目に入るので更新も忘れづらく、コードレビューも1ファイルの差分で完結するため、仕様が実装と乖離したまま放置されることを防ぎやすくなります。
Markdown 記法が使える点も重要で、 <spec> ブロックはデフォルトで Markdown をサポートしているので、人間にとっても非常に読み書きしやすく、レビュー時にも差分を比較しやすくなります。これはコメントや JSDoc では実現できません。
AIに対しても、チャットで追加修正指示をする場合に「 <spec> タグも一緒に更新してください」と指示するだけで、最新の仕様が反映されます。
仕様書を使い捨ての生成物ではなく継続的なソースとして活用することで、「仕様駆動開発」と「アジャイル開発」を両立できるのです。
AI 時代の最適解は SFC(単一ファイルコンポーネント)?
この <spec> アプローチを実践してみて、「Vue の SFC (Single-File Component) は AI 時代に最適なフォーマットなのではないか」と強く感じるようになりました。
Vue SFC は元々、 <template>, <script>, <style> という個々のブロックを本質的に結合されているべき関心のまとまりであると見なして、その単位でカプセル化されたコンポーネントを組み合わせて UI を作る思想です。
だからこそ、コンポーネントごとに仕様を定義できること、コンポーネントと仕様が1対1で紐づくことは理に適っています。
1ファイルに複数コンポーネントを書ける React の JSX と比べて、 Vue の SFC は柔軟性に欠けるという見方もありました。しかし AI 開発においては、この「1ファイルに1コンポーネント」という制約がむしろ優位性になると考えています。
Vue SFC だからこそ実現できる、ファイルに直接仕様を書くという仕様と実装の完全なコロケーションが、AI のポテンシャルを最大限に引き出せるのです。
まずは一部のコンポーネントに対して導入するだけでも、AI の出力が安定することを実感できると思いますので、ぜひ試してみてください!
参考
こちらもオススメです
Discussion