Copilot + Claude Sonnet 4 でショッピングサイト風なものを作る

ここ数年、新人研修でハンバーガー注文サイトと管理画面を作っている。最初は Vue2 ベースで web api を Laravel、次が Vue3 ベースで web api が Laravel、今年は、Vue3/Nuxt.js で web api が Laravel という形になっている。

ここ数年でシングルページアプリケーション(SPA)の風潮から再びサーバーサイドレンダリング(SSR)に戻ってきている感じで、Vue2 にしても、Vue3/Nuxt3 という変化からそれに続いする形で課題も変わってきているわけですが。

この課題の目的としては

  • 注文サイトのような主に GET が多く使われて、レイアウトが重視される別々な画面設計
  • 管理サイトのような CRUD のパターンが多く使われ、画面が量産できるパターン

を実体験するというものがある。

個人的に言えば、後者の管理サイトみたいなのは Ruby on Rails などの特定ツールを使って一気に作ってしまうほうがよい。開発プロジェクトにとって、管理系の画面は定型のものが多く、利用者はコンピュータ―にある程度強いという前提が成り立っている。なので、多少レイアウトや使い勝手を犠牲にしてでも、MVCパターン系のツール(CakePHPのbekeとか)を使って100枚ぐらい一気に作ってしまうと、またそれ系のツールを自作して一気に作るほうがよい。

とは思うんだが、開発者それぞれなので。。。

折角なのでReactで作る

100億年振りに触るのですが、Reactで作ってみます。確か Scratch の中身を改造しようとしたときとか、React Native や Expo でアプリを作ろうとして挫折したとか、別件だけど Flutter のコードに辟易してしまったとき以来なわけで、どうも JSX 形式が慣れないんですが。まあ、生成AIを使ってやって貰うんだったら何でもいいですよね。という訳です。

クイックスタート – React https://ja.react.dev/learn

実は、最初は Copilot を使ってコードをちまちま修正するかと思っていたのですが、なにか勢いで Copilot が直接コードを触ってくれるモードがあったので、うっかりと同意してしまった次第です。

ひとまず、VSCode + Copilot の状態で「Agent」モードを有効にします。ちょっと前まで、Github 上でレポジトリを変更するとかなんとかいう機能を紹介していたような気がするのですが、まあ、これでコードを Copilot が触ってくれます。実際には内部で Claude Sonnet が動いています。

この手のコード生成ツールは色々と違いがあるようですが、私の使い方だとどれも大差がありません。最初にでかい設計書や厳密なプロンプトを作っておいて、一気に生成しようという方が多いのですが、それだと違いが出るとは思いますが、私はそんな使い方をしません。アジャイル開発風にペアプログラミングをしていきましょう。生成AIにコード生成を頼みながら、テストやコードのレビューをしつつ、再びプロンプトに追加分を打ち込んでいけばいいわけです。ペアプロで対話をすればいいわけです。

余談ですが、厳密な設計書は厳密なプロンプトから目的のサイト作成を一気に作るように頑張る位だったら「厳密な設計書は設定から目的のサイトを自動作成するツールを作成する」のがベターですね。つまりは、先の Ruby on Rails のようなツールを生成AIに作って貰う乃至は協同で作るといパターンです。魚を得るのではなくて釣り竿を作るとか、金を掘るのではなくてツルハシを売るとかジーンズを売るとかそいうレベルの話です。

ページ単位でプロンプトで指示する

npx create-next-app@latest

で next.js のプロジェクトを作成した後に vscode で開きます。

Coilot は “Agent” モードにしておきます。普通のチャットを使いたいときは “Ask” にすれば ok です。

npm run dev

しておいて、画面が確認できる状態にしておきます。

仕事だと画面設計から入るとか共通のフレームワークがあると思うのですが、そのあたりは「プロトタイプを作る」ことに割り切ってしまいます。協同作業なので Copilot がやりやすいように作って貰いましょう。

カテゴリ一覧のページを categories.tsx で作成して。

以前のチャットだとちまちまと手作業でコードに入れる(あるいはコード上でチャットに聞く)ことが主流でしたが、エージェントモードだと書くコードに直接手をいれてくれます。Microsoft 365 の Copilot もこれくらい手を入れてくれるとよいのですが、そのうち変更してくれるかもしれません(パワポはちょっと手をいれてくれる)

コード変更に関しては「保持する」ボタンをぽちぽちと押していきます。本当はコードレビューをしたほうがいいのでしょうが、中身を読んでもあまりよくわからないし、なによりも JSX を触りたくはないですからね。Copilot によしなにやってもらいましょう。

ほどよくダミーデータをいれてくれて、カテゴリ一覧ができます。目的はハンバーガーサイト(モスのネット注文 https://www.mos.jp/service/shop/netorder/ )を想定しているので、ハンバーガーのカテゴリにしたいです。

カテゴリ一覧の web api は localhost:8000/mos/api/categories を使って。
JSON 形式の例

{
"items": [
{
"id": 1,
"slug": "special1",
"title": "今月のお薦め",
"description": "今月のお薦め商品を紹介します。",
"image": "",
"sortid": 1,
"display": true,
"created_at": "2025-06-05T11:57:01+09:00",
"updated_at": "2025-06-05T11:57:01+09:00",
"deleted_at": null
},
{
"id": 3,
...

既に web api は Laravel で作ってあるので動作が可能な状態です。新人教育でも web api は提供するパターンで画面を Vue3/Nuxt で作って貰っています。web api まわりはデータベースアクセスなどの範囲が広いのとルーティング設定や Controller やらとややこしいことが多いので、提供することにしています。このあたり、良い教科書がないですかね? Web APIの設計の本は小難しいものが多いのです。

いろいろ追加されていますが、ひとまず「保持する」してしまいます。実際のコードの場合は、git への commit 単位にして気に入らなかった戻せばいいんじゃないでしょうか?

カテゴリ一覧のページとカテゴリ内の商品のページが表示されます。商品のほうはまだダミーデータですね。このあたりは、最初のところで web api の一覧とか OpenAPI を使って情報を突っ込んでやるうまく解析してくれるかもしません。今回は最初なので1手順ずつやっています。しかも、このブログを書きながらリアルタイムでやっている。

カテゴリ内の商品を表示するときは web api で /products/slug/{category_slug} を使って。
商品を選択したときは、/products/{product} を使って、商品の詳細ページを表示して。

Copilot が作ったページがちょっと違うので、Copilot に直して貰いましょう。そもそも、Copilot あるいは Claude Sonnet の書きやすい形でコードを生成しているので、それ自身が理解しやすいはずです。このあたり

  • 新規で Claude Sonnet を作成して、さらに Claude Sonnet で修正する
  • 人間が書いた既存のコードを Copilot が解析して Claude Sonnet が修正/追加していく

という2つのパターンがあると思います。で、おそらく前者のほうが生成AIにとっては楽でしょうね。学習済みのコードをを出してくるのですが、それを解析/学習するのは容易なはずです。ですが、後者のほうは人間の「理解不能なコード」を理解しないといけません。このあたり、生成AIの都合の良いほうに寄せるのは重要だと思っています。

もちろん、後者も必要なんですけどね。ちなみに不味いコードは Claude Sonnet が書き変えてしまうので、かなりリスクが高いです(いろいろな意味で)。

大体意図した通りになっているのですが、商品詳細のほうが違っています。

商品の詳細を表示する場合は /products/{id} のように id を使って。

これは laravel の api.php の書き方が悪いのですが、実際は id を設定します。

windows 上なので mv コマンドがなくて失敗していますが、PowerShell でやり直しています。ファイルを消すコマンド等は「続行」ボタンを押すみたいです。

X とかで「ファイルが消されてしまった!」現象が多くみられるので、その対策みたいですね。まあ、git に履歴が残っていれば復活できるのと、github actions と連携すると取り返しがつかないので、そこは人間がやっても生成AIがやっても一緒な話です。気を付けましょう、ということで。

ひとまず「カートに追加」」ボタンまでできました。ボタンはできているけど、コードの中身はない状態ですね。ここまで、概ね2時間ぐらいです。動作を確認しながらだし、ブログで記録をつけながらなので、そこそこ時間がかかっているかもしれませんが、ペースとしてはこれぐらいでしょう。

React/Nuxt慣れしていれば、人が単体でももっと素早くできるかもしませんが、これ以上ペースを上げても疲れるだけなので、検証としてはこの程度でいいんじゃないかなと思います。これをもっと早くしたい場合は(例えば100画面同時につくるとか)、先に書いた通り Ruby on Rails 形式で別途共通フォーマットや共通データを作成しておいて、生成AIに量産するツールを作ったもらったほうがよいです。そのあたりの線引きをペアプロ型のプロトタイプ開発に落とし込むか、オートメーションの大量生産型に落とし込むかですね。ブラウザ上で、さっくりと管理画面系ができますのようなキントーンを使った場合は後者のほうがベターだと思います。

さて、お昼を食べてから続きをやりましょう。

どうせなのでモスバーガーに行ってこよう。

昼から続き…

商品詳細の「カートに追加」機能を実装して。
カートの内容を cart.tsx で表示して。

この手の商品サイトには必須のカート機能を入れる。カテゴリ一覧も商品一覧も何処にもあるものだし、カート機能も定番のものなので、どこからか参考になるものを引っ張ってくればok

定番のものは人が作ってもAIが作っても同じなわけで、この場合は生成AIに作ってもらっている。新人研修の場合は、これとほぼ同じものを新人に手作業で作って貰っている。これはこれで意味があることで、

  • Vue3やTypeScriptの文法を覚え、実際に使ってみる
  • 動かした時にエラーが出るので、エラーの見方や直し方を学ぶ
  • 後から追加機能をいれるときに、入れやすいわかりやすいコードを心がける

という仕事上に必須な技術を学ぶためである。目的として「注文サイト」だけ作るのであれば Copilot に注文ページを作って貰えばいいわけだが、デザインにせよコードにせよ、何かを変えたり何かを修正したりすることが生成AI頼みではやりづらい。

実際、Claude Sonnet が出力してくるコードを手作業で直すのはちょっと辛いカモ。コードが揃っているという点ではコード規約に即していて読みやすいけど、共通化&ライブラリ化されているとは言い難いですよね。

カートの「注文に進む」をクリックしたときに
POST /mos/api/orders で、注文を実行して。

JSON形式の例

{
total_price: 0,
total_quantity: 0,
items: [
{
id: 1,
price: 1000,
quantity: 2,
},
{
id: 2,
price: 2000,
quantity: 3,
},
],
}

送信するJSON形式は、OpenAPIの形式でも上記のように例を示してもokです。

注文した結果の JSON が
{ "order_number": "07029999" }
となるので、この order_number をユーザーに表示して。

レスポンスに注文番号(order_number)が入っているので完了ページに表示させます。

これで機能は大体揃ったので、後は全体のデザインを整えていけばいいでしょう。ヘッダーとフッターを付けておきます。多分 layout.tsx なんですが、これも Copilot 経由で仮に付けてしまう。

全体のヘッダーとフッターを付けて。

ヘッダーは「新人研修のための注文サイト(仮)」
フッターは、coplyleft by moonmile

ここで、全 page.tsx に手を入れているのがさすが! Claude Sonnet ですね。

人がやるならば、クラスを使って共通化するとか各ページの記述場所を共通化するとか省力化するわけですが、Claude Sonnet はちらかった className の記述をひとつひとつ直していきます。おそらく100画面があれば、100画面直しておくと思われます。

ここは機械ならではというところで、人間の開発者とはアプローチが違うところです。逆に言えば、人間の開発者には修正がしにくいということです。

ひとまず、ここまで出来たのでokとしましょう。細かいところを見ると

  • トップページにある「商品一覧」は不要
  • パンくずリストが残っているページがある
  • 注文が完了しました、から自動的にトップページに戻ってしまう
  • カテゴリ統計とかは必要なし

など、手をいれる必要がありますが概ねの動きはこんな感じです。

サンプルコード

Copilot + Claude Sonnet 4 でショッピングサイト風のサンプル
https://github.com/moonmile/mos-next-sample

カテゴリー: 開発 パーマリンク