React +Laravel12 での開発~Laravel12はBladeで完結できるが、要件が高度化するほど React → Next.js の順にシフトしていく

React +Laravel12 での開発~Laravel12はBladeで完結できるが、要件が高度化するほど React → Next.js の順にシフトしていく

Laravel12ではBladeを使ってビューまで作成できるが、要求の高いユーザインターフェイスを実現するにはフロントエンド側の開発比率が高くなってくる。特にUI/UXを実現するために要件が複雑になってくると、JavaScript/TypeScriptで実装することもできるが、コンポーネント化や再利用性を考えた場合にはReactを選択したほうがよい。さらには、レンダリングの制御までを含めて考えなければならないときにはNext.jsを選択することになる。

Laravel12 ビュー開発の選択指針

  1. Blade
    • 特徴: Laravel標準のテンプレートエンジン。サーバーサイドレンダリング(SSR)で動作。
    • 向いているケース: 管理画面、CRUD、帳票画面など「UI要件がシンプルで、SEOも欲しい」ページ。
    • メリット: 学習コスト低い、開発効率高い、Laravelと密結合。
    • デメリット: 複雑なUI/UXには不向き。JSのスパゲティ化リスク。
  2. React
    • 特徴: コンポーネント指向のUIライブラリ。フロントエンドで状態管理・イベント制御を強化できる。
    • 向いているケース: インタラクティブ性の高い会員画面や検索UI、操作性重視のSPA部分。
    • メリット: 再利用性の高いUIコンポーネント設計が可能、動的UIに強い。
    • デメリット: SEO対策は弱くなる(CSR中心)。Laravelとの統合にはInertiaやAPIが必要。
  3. Next.js
    • 特徴: Reactベースのフレームワーク。SSR/SSG/ISRを選べるため、レンダリング制御まで担える。
    • 向いているケース: ECサイトの公開商品ページ、SEOが必須なトップページやLP。
    • メリット: SSR/SSGでSEOに強い、柔軟なレンダリング制御、CDN連携による高速配信。
    • デメリット: フロントとバックエンドが分離するため、構成・運用が複雑化。

選択の流れ(開発比率 × UI要件 × レンダリング要件)

  • UIがシンプル & 開発スピード優先Blade
  • UIが複雑 & 再利用性・保守性重視React (Inertia.js経由 or API連携)
  • UIが複雑 & SEO/レンダリング制御も必須Next.js

このあたりを含めて、開発まえに、技術的要素の選択には何について考えて決めていかなければいけないかを整理していこう。

基盤セットアップ

目的: 開発環境・依存関係・ツールを最初に固め、後の手戻りを最小化する。
概要: PHP 8.3 / Composer / Node を揃え、Docker で環境を統一。品質系(Pint, Larastan, Pest)や監視・権限管理パッケージを初期導入し、CI/CD をすぐ動かせる状態にする。

ランタイム: PHP 8.3 / Composer 2 / Node 20 / MySQL 8 か PostgreSQL 16(本番は InnoDB 並列DDL or PG のロック戦略を想定)

コンテナ: Laravel Sail or Docker Compose(app/web/queue/schedule/db/cache/search を分離)現在は、Dockerで直接コンテナを構築している。(コンテナ構成については別途参照)

パッケージ標準装備

  • 品質: laravel/pint, phpstan/phpstan(+ nunomaduro/larastan), pestphp/pest
  • 開発可視化: laravel/telescope(本番は権限/環境で制御)
  • 認可/役割: spatie/laravel-permission
  • 設定/状態: spatie/laravel-settings or Config+DB
  • ログ/監視: Sentry or Bugsnag, spatie/laravel-health
  • API スキーマ: darkaonline/l5-swagger or vyuldashev/laravel-openapi
  • 検索: Laravel Scout + Meilisearch / Algolia(Postgres なら pg_trgm も検討)
  • 画像/メディア: spatie/laravel-medialibrary
  • データ変換: spatie/laravel-data(DTO)

ブランチ運用: trunk-based(main + 短命 feature ブランチ)+必ず PR・CI

CI/CD: GitHub Actions(lint→static analysis→unit+pest→build→deploy)。デプロイは Laravel Forge/Envoyer or 自前の rolling/blue-green

Dockerコンテナのおかげで開発生産性は飛躍的にあがった。疑似的な開発環境が引き起こす問題は、開発環境では動いたのに、本番環境やステージング環境では動作が違うとか動かないとかの差異が発生する。本番だけ動くなんてこは少ない。そんな場合でも本番だけで動けばいいやという問題でもない。

Windowsでの場合には、WSL(WSL2)を利用する方法とWSL2上にUbuntu VMを置く方法がある。

バリエーションの区別

  • WSL1
    • Windows のシステムコールを変換して Linux バイナリを動かす方式
    • 仮想化ではなく互換レイヤー
    • Docker 等の本格利用はほぼ不可(cgroups 等がない)
  • WSL2
    • Hyper-V 上に軽量 VM として Linux カーネルを動かす方式
    • 完全な Linux カーネルを持ち、Docker がそのまま動作
    • I/O や systemd も対応しており、通常の開発環境として十分
  • WSL2 + Ubuntu VM(VirtualBox/VMware/Hyper-V などで別途立てる)
    • WSL2 自体とは別に「完全な Ubuntu サーバ」を VM として用意
    • その中で Docker / k8s を実行
    • WSL2 はあくまで「Windows からの開発アクセスのための橋渡し」
項目WSL1WSL2WSL2 + Ubuntu VM
導入の容易さ◎ Windowsに標準機能wsl --install で即利用△ VMイメージ作成+ネットワーク設定
Linux互換性△ カーネル非搭載、制約多い◎ カーネル搭載で本物のLinux◎ 完全なUbuntu
Docker対応✕ 非対応◎ ネイティブ利用可◎ 本番同等
パフォーマンス○ ファイルI/O高速(Windows直結)✕ Linuxネイティブ性能なし◎ ネイティブLinuxに近い○ VMオーバーヘッドあり
Windowsとの統合◎ Windows FSに直アクセス○ 共有可能だが I/O遅め△ 共有フォルダ/SSH設定必要
ネットワーク再現性△ 制約多い○ 単一環境なら十分◎ VMごと独立、複数ノード検証可
運用負荷◎ 少○ 普通△ VM更新・管理が必要

WSL1

  • もう歴史的経緯のみ。現在は非推奨。
  • 「軽く Bash を叩く」用途以外は使わない。

WSL2

  • Laravel/Next.js/React の開発、単一コンテナ、DB連携など 通常の開発用途はすべてこれで十分
  • VSCode Remote - WSL との相性も◎。

WSL2 + Ubuntu VM

  • k8s クラスタや複数ノードのネットワーク検証、本番同等構成の再現が必要なときに選ぶ。
  • リソースをVM単位で固定できるので、負荷試験にも有効。

2) アーキテクチャ原則

目的: アプリが大規模化しても見通しを保ち、責務を明確にする。
概要: ドメイン/アプリケーション/インフラ層を分ける。ユースケースごとにアクションやサービスを作り、入力(FormRequest+DTO)、出力(Resource/Blade)を明確化。
  • : Domain(エンティティ/値オブジェクト/ドメインサービス)/ Application(ユースケース=サービス or アクション)/ Infrastructure(Eloquent, 外部API)
  • Eloquentの使い所: 永続化境界(Infra)で使用。複雑クエリは Repository(クエリオブジェクト)へ分離。読み取りは ResourceQuery Builder で最適化。
  • 入力境界: FormRequest でバリデーション、DTO(laravel-data) で型安全にユースケースへ渡す。
  • 出力境界: Http\Resources(API)/Blade(SSR)/Inertia or Livewire(双方向)

3) データ設計&整合性

目的: データの信頼性を担保し、アプリ側で不具合を防ぐ。
概要: 外部キー・ユニーク制約を徹底、Enum はコードとDBを一致。マイグレーションは段階的。現実的なシーディングやベクトル検索まで意識しておく。
  • DB 基本: 外部キー・ユニーク制約・チェック制約・部分インデックス(PG)/ 階層インデックス(MySQL なら適切な複合)
  • Enum: PHP 8.1+ BackedEnum と DB enum/チェック制約を一致
  • マイグレーション: 破壊的変更は段階的(add→backfill→switch→drop)。大規模は gh-ost(MySQL)や “オンライン DDL” を意識。
  • シーディング/テストデータ: Factory + State を活用(現実的なサンプルを常備)
  • 全文/ベクトル: Scout+Meili / PG pgvector を分離テーブルで(更新はキューで非同期反映)

4) API とフロントの作法

目的: 利用者や外部サービスに一貫性あるI/Fを提供し、フロント実装をスムーズにする。
概要: RESTful + OpenAPI ドキュメント化。Blade/Alpine・Livewire・Inertia など UI スタイルを案件に応じて統一。認証は Sanctum/Passport。
  • API: リソース指向 + ページング + フィルタ・ソートは spatie/laravel-query-builder で統一。Problem Details 形式のエラー応答。
  • 認証: セッション/Blade は標準、SPA/API は Sanctum(Cookie ベース) or Passport(外部発行)。MFA は laravel/fortify + TOTP。
  • ドキュメント: OpenAPI 自動生成(注釈 or attributes)→ CI でスキーマ検証&公開。
  • フロント選択
    • 伝統: Blade + Alpine.js(軽量)
    • インタラクティブ: Livewire v3(フォームやCRUDが爆速)
    • SPA: Inertia(Vue/React) or Next.js/NUXT と疎結合 API
  • 資産ビルド: Vite(envごとに split)。Icon は Heroicons/Bootstrap Icons のみ等「厳選主義」

5) 非同期処理・スケジュール

目的: 重い処理や定期処理をアプリ本体から切り離し、スケーラブルに保つ。
概要: Redis+Horizonでジョブ管理。イベント駆動で疎結合化。定期処理は schedule() でIdempotentに。
  • Queue: Redis + Horizon(可視化)。重複排除(->onQueue('…') + job unique key)とリトライ戦略、失敗時は Slack 通知。
  • Schedule: app/Console/Kernel.php で idempotent 実装。ロングタスクは Job へ委譲。
  • イベント駆動: ドメインイベント(例:OrderPlaced)→ Listener(メール、インデックス更新、Webhook)で疎結合化。

6) 品質(テスト&静的解析)

目的: バグを未然に防ぎ、安心して改修できる基盤をつくる。
概要: Pest で読みやすいテスト、Factory で再現性あるデータ。PHPStan/Larastanで静的解析をCI必須化。API契約テストで外部連携も担保。
  • Pyramid: Unit(ドメイン)> Feature(HTTP/DB)> 少量の E2E。Pest で読みやすく。
  • Fixtures: Factory + 建設者パターン(テストの意図が読めるデータ生成)
  • 静的解析: PHPStan(Lv8〜max)+Larastan。CIで必須pint は pre-commit。
  • 契約テスト: OpenAPI スキーマ検証、外部APIは Contract/Stub を採用。

7) セキュリティ

目的: 標準機能だけでなく権限・秘密情報管理まで網羅し、安全なサービス運営を実現する。
概要: CSRF/XSS/Rate Limit 基本対策。spatie/permission でロール管理。アクションログや秘密管理(Vault/SSM)を徹底。
  • 基本: CSRF, XSS(Blade エスケープ徹底), Rate Limit(Route::middleware('throttle:…')
  • ヘッダ: spatie/laravel-csp / secure-headersSameSite/HttpOnly/Secure クッキー
  • 権限: Policy/Gate + spatie/permission(ロール/権限)を必ずテスト
  • 監査: spatie/laravel-activitylog(重要操作の追跡)
  • 秘密管理: .env は Vault/Parameter Store。キー回転ポリシーを運用設計に含める。

8) パフォーマンス & 可観測性

目的: 運用後のスケールやトラブル検知を前提に、速さと見える化を確保。
概要: N+1回避、キャッシュ戦略、Octane導入の検討。ログを構造化し、SentryやAPMで監視。/healthで外部監視連携。
  • ボトルネック回避: N+1 は ->with()->loadCount()、集計は DB 側、重い一覧はカーソル or paginate()
  • キャッシュ: 設定/辞書は Cache::remember(), ビューはフラグメントキャッシュ。Cache::tags()(Redis)
  • Octane: 高スループットが要件なら(Swoole/RoadRunner)。静的 state に注意し、依存の解放を徹底。
  • ログ/トレーシング: JSON ログ + 構造化(request_id, user_id)→ Sentry/Bugsnag + APM(Datadog 等)
  • ヘルスチェック: /health に DB/Queue/Cache/Storage の状態を露出(spatie/laravel-health

9) デプロイ運用

目的: 安定運用とゼロダウンタイムを確保し、リリースリスクを下げる。
概要: Blue-Green デプロイ、マイグレーションは Expand-Contract。キャッシュ系 Artisan コマンドはCI最後に。Backup と復旧手順をRunbook化。
  • ゼロダウンタイム: php artisan down --render は極力使わず、Envoyer/Forge か Blue-Green。
  • DB 変更: “expand-contract” 戦略(互換期間を置く)。大規模は夜間ロールアウト+強制ロールバック手順をドキュメント化。
  • シークレット/環境差分: .env.production はマネージドストアで一元管理。
  • アセット/キャッシュ: config:cache, route:cache, event:cache, view:cache を CI/CD の最後に。
  • バックアップ: DB/Storage を spatie/laravel-backup + 世代管理 + 復旧リハーサル。

10) チームの運用ルール(軽量ドキュメント)

目的: 技術的負債を減らし、誰でも開発・レビューできる文化を作る。
概要: ADRで決定を記録、PRテンプレやリリースノート自動化。ルールは軽量に、チーム全員が守れることを優先。

  • ADR(Architecture Decision Record): 重要決定は 1 ファイル 1 決定で履歴化
  • コーディング規約: 命名・ディレクトリ・例外/ログ方針・API エラーフォーマット・権限モデル
  • PR テンプレ: 背景/変更点/移行手順/リスク/確認観点/スクショ
  • リリースノート: 自動生成(Conventional Commits+Changesets)
 株式会社 iPLUS ONE