プロトタイプ開発環境というのは、雑に思いついたwebアプリを素早く作成するための環境のことで1年半くらい前にもこういう記事を書いた。
個人開発やサイドプロジェクトで「ちょっとしたアイデアを形にしたい」というときになんかゼロから環境構築するのは面倒だし、かといって適当に作ると後々メンテナンスが大変になる。
以前はViteを使って簡単なプロトタイプを作っていたが最近のAI Codingの進化によりプロトタイプ以上にしっかり動くものまで簡単に作れるようになってきた。そうなるとpure viteより最初からもう少し大袈裟だけども発展性のある技術スタックで作っても良いのではないかと思う。
また、転職して以来Cloudflareを触っていなかったし、最近はNext.jsも触っていなかったので、その辺りのキャッチアップも兼ねて試行錯誤してみることにした。結局RSCに慣れないおじさんなのでPages Routerを採用してしまったが、あくまでプロトタイプ開発環境という域を出ないという制約は掛けつつも、今一度自分用に作り直してみた。
この記事はその成果物と実装過程のメモ。ちなみにClaude Codeを使う練習も兼ねてClaude Codeと共に実装を進めた(MAXプランを使えるほどの富豪ではないので3.7 sonnet製です…)。
フレームワークとランタイム
プロトタイプ開発環境として、以下の技術スタックを選定した。
- フレームワーク: Next.js 15+ (Pages Router)
- 言語: TypeScript
- UI: React 19+、TailwindCSS
- リンター/フォーマッター: Biome
- Git フック: Husky (pre-commit)
- CI/CD: GitHub Actions
- デプロイ: Cloudflare Pages (OpenNext使用)
Next.jsを選んだ理由は、個人的に慣れていることと、プロトタイプから本格的なアプリケーションまでスケールできる柔軟性があるから。特にPages Routerは使い慣れていて、シンプルな構成で始められる点が魅力的(serverとかclientとか考えたくないんじゃ)。
Cloudflareを選んだのは、無料枠が寛容で、個人開発には十分な機能が提供されているから。また、D1やKV、R2、Queueなど(最近だとAIサービスもある)のサービスも必要に応じて簡単に追加できる点も良い。
Remixはそもそも思想的に合わない感じがあったので除外。まぁプロトタイピングだし慣れてて好きなもの使うのが一番良い。
開発環境の整備
開発環境としては、以下のツールを導入した。
- Biome: ESLintとPrettierの代替
- Husky: コミット前に自動的にlintやformatを実行したくて入れた(とりあえず入れたがいらねぇという可能性もある)
- TypeScript: 型安全性を確保し、開発体験を向上
- TailwindCSS: 迅速なUIデザインのため
特にBiomeは設定が簡単で高速なのが好き。もう1年以上前から使ってる。
{
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"correctness": {
"useExhaustiveDependencies": "error"
},
"suspicious": {
"noExplicitAny": "error"
}
}
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2
}
}
基本構成の作成
まずは基本的なNext.jsアプリケーションを作成した。Pages Routerなシンプルなディレクトリ構成を採用しコードの整理と保守性を重視。
基本的なディレクトリ構成は以下のようになっている。(ちなみにこの構成はOpenNextで生成されたものをちょっといじったもの)
/
├── src/
│ ├── pages/ # Next.js Pages Router
│ │ ├── api/ # API Routes
│ │ ├── _app.tsx # アプリ全体の設定
│ │ └── index.tsx # ホームページ
│ ├── components/ # 再利用可能なUIコンポーネント
│ ├── lib/ # ユーティリティ関数・共通ロジック
│ ├── styles/ # グローバルCSS・TailwindCSS
│ └── types/ # TypeScript型定義
├── public/ # 静的ファイル
└── CLAUDE.md # LLM開発ルール
特に言及すべき点はないけどClaude Codeを使ってるのでCLAUDE.mdが鎮座している。
CI/CDの設定
次に、GitHub ActionsでCI/CDを設定した。プロトタイプとはいえ速度と品質を担保するための自動化は重要。
CI用のワークフローでは、以下のジョブを設定している。
- lint-and-typecheck: コードの品質チェック
- build: アプリケーションのビルド
- security: セキュリティ監査
- multi-node: 複数のNode.jsバージョンでのテスト(が、Actionsを早く終わらせたいので1つしか指定してないけど)
name: CI
on:
pull_request:
branches: [main]
jobs:
lint-and-typecheck:
runs-on: ubuntu-latest
name: Lint and Type Check
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run linter
run: npm run lint
- name: Run type check
run: npm run type-check
デプロイ用のワークフローでは、mainブランチへのプッシュ時に自動的にCloudflare Workersにデプロイするように設定した。
name: CI/CD
on:
push:
branches: [main]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy to Cloudflare (Production)
run: npm run deploy
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
これだけ。
Cloudflareの設定
Cloudflareへのデプロイ設定も行った。重要なのはwrangler.toml
の設定。これはCloudflare Workersの設定ファイルで、OpenNextで生成されたアセットをどのように配信するかを定義している。最初、Claude Codeが.gitignoreにwrangler.toml
を追加してしまっていてCDが失敗してキレた。
main = ".open-next/worker.js"
name = "prototyping-base"
compatibility_date = "2025-03-25"
compatibility_flags = ["nodejs_compat"]
[assets]
directory = ".open-next/assets"
binding = "ASSETS"
[env.development]
vars = { NODE_ENV = "development" }
[env.production]
vars = { NODE_ENV = "production" }
また、Cloudflareの型定義を自動生成するスクリプトも追加した。これにより、TypeScriptでCloudflareの機能を型安全に使用できる。
{
"scripts": {
"cf-typegen": "wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts"
}
}
Claude Codeを使った開発
今回の実装では、Claude Codeを使う練習も兼ねて開発を進めた。最初はVSCode内の拡張でClaude Codeを使っていたが、エディタが狭すぎるしコーディング作業を占有してしまって邪魔だったので、shellで実行するようにした。
細かい修正は手動でやって、裏でClaude Codeも実行されているイメージ。CI/CD周りは実際にGitHubでの実行状況を見て調整が必要で相変わらず面倒だった。Claude Code Actionsあたりでインクリメンタルにやればよかったかもしれないが、自分はClaude Code Actionsが作成したPRを結局手元で実行しないとマージできないようなチキン人間なのでうまくいかなかった。
とりあえず今回使ったプロンプトを置いておく。ハッカソンに参加するという良い感じのハッタリをかましている。
プロンプト
今週末にハッカソンに参加します。ハッカソンではプロトタイプのアプリを開発する予定です。私はエンジニアとして参加します。当日は素早く開発できるようにLLMを使って開発していく予定です。そのための環境整理したいです。一緒に参加するPdMに「こういうアプリが作りたい」と言われた時にこの環境を使って開発がすぐに始められると嬉しいです。
以下に開発環境として考えていることを箇条書きしました。これを元に開発環境として最低限整えておくべきREADMEやLLM向けのrulesファイルなど必要になりそうなものを作成してください。時間はたっぷりあるのでハッカソン当日を想定してじっくりと考えてください。
# 私が考えていること
- どうせ当日は開発時間がないはずなので基本的にLLMで生成したい
- 想定するワークフロー
- プロンプト
- UI生成
- 機能実装
- デプロイ
- rulesファイルや利用する言語やフレームワークを整えておくべき
- 絶対に守るべきこと
- 極力シンプルなアーキテクチャにする
- ドキュメントやコードコメントには日本語を使う
- 使用する技術はできるかぎり最新のバージョンを使う
- このリポジトリはパブリックに公開するので秘匿情報を含まないようにする
- このリポジトリはパブリックに公開するので汎用的に使える記述を心がけること
- 検討事項
- 開発環境は何を使うか?
- 言語はTypeScript
- フロントエンドはReact。versionは19以上。
- バックエンドはNode.js
- フレームワークはNext.js。versionは14以上。Pages Routerしか使わない想定。
- CSSフレームワークはTailwindCSS。
- DBはどうするか?
- 不要ならSSGや簡単なSPAで良い
- 動的な画面でも思い切ってJavascriptやHTMLにjsonを埋め込んでおくとかでも良さそう
- CloudflareのD1を使う
- ORMは使わない
- UIのデザインはどうするか
- 自分はFigmaなどのデザインツールを使えない
- プロトタイプ開発なのでデザインはAIに任せる
- デプロイ先はどうするか
- CloudflareをPlatformとして利用したい
- サーバーはWorkersかPagesを使う
- 静的ファイルはR2を使う
- キャッシュ用途はKVを使う
- DBはD1を使う
- 非同期処理はQueuesを使う
- その他にクラウドサービスが必要な場合はCloudflareのドキュメントを読んで探して利用する
- 詳しくは[Cloudflare Workersのドキュメント](https://developers.cloudflare.com/workers/)を参照
- このリポジトリに必要なもの
- LLM用のrulesファイル
- packages.json
- README.md
- 特にどうやって開発を進めるべきかについては記載すべき
- Linterの設定
- Formatter(biome)の設定
- Typescriptの設定
- TailwindCSSの設定
- env系のファイルの設定
- CloudflareでNext.jsアプリを作る方法をREADMEに記載すること
- 例えば`npm create cloudflare@latest -- my-next-app --framework=next`でnext.jsアプリを作成するなど
- このリポジトリに不要なもの
- サンプルアプリケーション
- テンプレートとしてのアプリケーションのコードは不要
- 具体的な実装
- ハッカソンについての情報
- このリポジトリはパブリックに公開するのでハッカソンの情報などは不要。
wrangler types
いつからかわからないがwranglerにBINDINGの定義に合わせて型定義ファイルを生成してくれる機能が追加されていた(多分
v4.0以降)。ルートディレクトリにworker-configuration.d.ts
というファイルが追加される。npm run cf-typegen
で生成できるようにしてhuskyに追加してある。
CloudflareとNext.jsの実行環境の変化
CloudflareとNext.jsの実行環境が変わっていることを知った。以前はnext-on-pagesというビルドツールを使っていたが、現在は異なるアプローチが採用されている。
詳しくはCloudflareの公式ドキュメントに記載されているが、OpenNextというプロジェクトがNext.jsをVercelと同様に様々なランタイムで動かせるようにする活動を行っており、Cloudflare WorkersでもNext.jsがほぼちゃんと動くようになっていた。
OpenNextについて
OpenNextは、Next.jsアプリケーションを様々なプラットフォームで実行できるようにするためのツールだ。Cloudflare Workers用のアダプターに関しては、Next.jsでビルドしたoutputをwranglerで実行できるように変換しているっぽい。
具体的な実装はopennextjs/opennextjs-cloudflareで確認できる。OpenNextでビルドすると.open-next
というディレクトリが作成され、その中にworker.js
が生成される。つまり、Next.jsでビルドしたoutputをWorkerで実行できる形式に地道に変換しているということだ(next-on-pagesと同じ?)。お疲れ様です。
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
export default defineCloudflareConfig();
このシンプルな設定だけで、Next.jsアプリケーションをCloudflare Workersで実行できるようになる。
今回は自分用のプロトタイプ開発環境を整理し、Next.jsとCloudflareを使った構成を作成してみた。この環境を使えば、アイデアを素早く形にしつつも必要に応じて本格的なアプリケーションに発展させることも可能。
特にCloudflareのサービス群(Pages、Workers、D1、KV、R2等)を活用することで、バックエンドも含めた完全なアプリケーションを構築できる点が良い。またGitHub Actionsを使ったCI/CDの自動化により開発からデプロイまでのフローもスムーズになるはず。
とはいえそもそもこんな環境を作る必要ありますか?という問いはあり、プロトタイピングならLLMでゼロから毎回作れば良いじゃんという主張もわかる。ただLLMは確率論的にアウトプットを出力するわけでその出力の精度を上げるには適切なガードレールが必要である。ローカルで動かすだけならrulesなんかで縛るだけで良い気もするが、今回作ったリポジトリはデプロイやCI/CDまで動く状態で作ってあるので公開&運用くらいまで見据えられる。rulesを大量に書くくらいならわかりきってる土台の構成は作っちゃっておいて、rulesにはアプリの出力情報だけ書いて開発させる方が出力精度も向上するんじゃないかという気がする。
関係ないけどClaudeとCloudのスペルが似てるせいでタイポが死ぬほど発生して辛い…。100回くらいClaudeflareと打った。
参考リンク
Views: 0