Skip to content

ビルド・デプロイ

デプロイパイプライン全体図

Vite ビルド設定

vite.config.ts(予定)

typescript
import { defineConfig } from 'vite'

export default defineConfig({
  build: {
    // 出力先
    outDir: 'dist',

    // バンドルサイズ警告閾値
    chunkSizeWarningLimit: 500, // 500KB

    // Tree-shaking + Code Splitting
    rollupOptions: {
      output: {
        // Three.js を個別チャンクに分離
        manualChunks: {
          three: ['three'],
          postprocessing: [
            'three/examples/jsm/postprocessing/EffectComposer',
            'three/examples/jsm/postprocessing/RenderPass',
            'three/examples/jsm/postprocessing/UnrealBloomPass',
          ],
        },
      },
    },

    // gzip 圧縮後のサイズを表示
    reportCompressedSize: true,

    // ソースマップは本番では無効
    sourcemap: false,

    // アセットのインライン閾値(4KB以下はBase64化)
    assetsInlineLimit: 4096,
  },

  // 本番ビルドの最適化
  esbuild: {
    // console.log を本番で除去
    drop: ['console', 'debugger'],
  },
})

Tree-shaking のポイント

Three.js は全体で約600KBあるが、必要なモジュールだけをインポートすることで大幅に削減できる。

typescript
// NG: Three.js 全体をインポート(600KB+)
import * as THREE from 'three'

// OK: 必要なクラスのみインポート(Tree-shaking が効く)
import { Scene, PerspectiveCamera, WebGLRenderer } from 'three'
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer'

想定バンドルサイズ

チャンク内容サイズ目安(gzip後)
index.jsゲームコア、UI、ロジック~80KB
three.jsThree.js 本体~150KB
postprocessing.jsポストプロセス~30KB
assetsテクスチャ、モデル、音声~500KB~1MB
合計~800KB~1.3MB

Cloudflare Pages デプロイ

手動デプロイ(開発時)

bash
# ビルド
npm run build

# Cloudflare Pages にデプロイ
npx wrangler pages deploy dist/ --project-name=rift-survivors

プロジェクト初期設定

bash
# Cloudflare Pages プロジェクト作成(初回のみ)
npx wrangler pages project create rift-survivors --production-branch=main

カスタムドメイン(任意)

Cloudflare Pages はデフォルトで rift-survivors.pages.dev のドメインを提供する。 カスタムドメインが必要な場合は Cloudflare Dashboard から設定可能(追加費用なし)。

GitHub Actions CI/CD

設計書デプロイ(既存)

deploy-pages.yml で設計書(VitePress)を GitHub Pages にデプロイ済み。

ゲーム本体デプロイ(新規)

以下の GitHub Actions ワークフローでゲーム本体を Cloudflare Pages に自動デプロイする。

yaml
# .github/workflows/deploy-game.yml
name: Deploy Game to Cloudflare Pages

on:
  push:
    branches: [main]
    paths:
      - 'src/**'
      - 'public/**'
      - 'package.json'
      - 'vite.config.ts'
  workflow_dispatch:

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm

      - run: npm ci

      # 型チェック
      - run: npx tsc --noEmit

      # ビルド
      - run: npm run build

      # バンドルサイズチェック(2MB制限)
      - name: Check bundle size
        run: |
          TOTAL=$(du -sb dist/ | cut -f1)
          MAX=2097152  # 2MB in bytes
          if [ "$TOTAL" -gt "$MAX" ]; then
            echo "::error::Bundle size ${TOTAL} bytes exceeds 2MB limit!"
            exit 1
          fi
          echo "Bundle size: ${TOTAL} bytes (limit: ${MAX})"

      # Cloudflare Pages デプロイ
      - name: Deploy to Cloudflare Pages
        uses: cloudflare/wrangler-action@v3
        with:
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
          command: pages deploy dist/ --project-name=rift-survivors

パイプライン構成図

環境変数

ゲーム本体

ゲーム本体はサーバーレスのため、シークレットは一切不要

環境変数必要性理由
API キー不要サーバー通信なし
DB接続文字列不要localStorage使用
セッションキー不要認証なし
暗号化キー不要ユーザーデータ未収集

CI/CD(GitHub Actions Secrets)

シークレット用途設定場所
CLOUDFLARE_API_TOKENwrangler 認証GitHub Settings → Secrets
CLOUDFLARE_ACCOUNT_IDCloudflare アカウント識別GitHub Settings → Secrets

シークレットの最小化

ゲームのコードやアセットにシークレットは含まれない。 CI/CD 用の Cloudflare 認証情報のみが必要であり、これはデプロイ時にしか使用されない。

デプロイ戦略

ブランチ戦略

ブランチデプロイ先用途
mainrift-survivors.pages.dev本番環境
feature/*<hash>.rift-survivors.pages.devプレビュー環境

ロールバック

Cloudflare Pages は過去のデプロイ履歴を保持しているため、 問題が発生した場合は Cloudflare Dashboard から1クリックでロールバック可能。

デプロイ頻度

  • 開発中(~5/1): 1日数回(機能追加のたび)
  • リリース後: 必要に応じて(バグ修正時のみ)
  • デプロイ所要時間: 約1~2分(ビルド + CDN伝播)