cockpit-nuxt-vuetify Nuxt 3 移行計画
背景
Herokuで運用中のcockpit-nuxt-vuetify(月額$7)をCloudflareに移行しようとしたが、Nuxt 2はCloudflare Pagesで動作しないことが判明。Nuxt 2自体のサポートも終了しているため、Nuxt 3への移行が必要。
現在のHeroku構成

| 項目 | 値 |
|---|---|
| アプリ名 | warm-plains-36011 |
| GitHub | keikomatsu/cockpit-nuxt-vuetify |
| Dyno | Basic ($7/月) |
| 起動コマンド | npm run start |
| デプロイ回数 | 199回 |
なぜ Cloudflare Pages に移行するか
- コスト削減: Heroku Basic Dyno $7/月 → Cloudflare Pages 無料
- パフォーマンス: Cloudflareのグローバルエッジネットワーク
- 簡単なデプロイ: GitHubとの自動連携
- 無料SSL: 自動でHTTPS化
移行方針: 新規プロジェクト立ち上げ
既存コードを書き換えるのではなく、新規Nuxt 3プロジェクトをゼロから作成し、必要な機能だけを移植する。
この方式のメリット
- 799ページ全部を移行しなくて良い - 必要なものだけ選んで移植
- UIを刷新できる - Vuetify 3のデザインをフル活用
- 技術的負債を持ち込まない - リファクタリングしながら進められる
- 段階的に切り替え可能 - 移行完了したページから順次公開
現状のトップページ構造
トップページ(pages/index.vue)には以下のコンテンツカードがある:
外部リンク(移行が簡単)
| カテゴリ | 内容 | 移行難易度 |
|---|---|---|
| Udemy動画講座 | 8講座へのリンク | 簡単 |
| Kindle本 | 2冊へのリンク | 簡単 |
Udemy講座一覧:
- 日商簿記3級編
- 会計・簿記入門編
- Excelショートカット編
- 財務3表編
- Excel基礎編
- Excelで財務三表編
- Excelでキャッシュフロー精算表
- Excelで連結会計入門
内部コンテンツ(静的ページ)
| コンテンツ | URL | 移行難易度 |
|---|---|---|
| 会計・簿記入門編 | /lessons/intro-to-accounting/ | 中 |
| 日商簿記3級_講義テキスト | /lessons/bookkeeping/chapter*/ | 中 |
| 日商簿記3級_スライド | /lessons/bookkeeping/slides/ | 中 |
| Excelショートカット編 | /lessons/excel-shortcuts/ | 中 |
| 財務3表編 | /lessons/financial-statements/ | 中 |
動的コンテンツ(問題集・テスト)
| コンテンツ | URL | 移行難易度 |
|---|---|---|
| 仕訳問題_分野別 | /sampleTest/boki3SampleTestByField | 中 |
| 日商簿記3級問題編 | /workbook/boki3 | 中 |
| 帳簿問題 | /workbook/continuousQuestions | 中 |
注: Firebase認証のコードは存在するが、ルートレベルの保護がなく実質的に未使用。未認証でもページにアクセス可能(空白表示になるだけ)。移行時に認証機能を実装するかは要検討。
旧プロジェクト規模(参考)
| 項目 | 数量 | 備考 |
|---|---|---|
| ページ数 | 799 | 全部は移行しない |
| コンポーネント数 | 219 | 必要なものだけ移植 |
| Vuexストア | 23ファイル | Piniaで再設計 |
| Vuetifyグリッド使用 | 9,394箇所 | 新規で書き直し |
移行戦略: 段階的リリース
Phase 1: 基盤構築 + トップページ
目的: 新Nuxt 3プロジェクトをCloudflareにデプロイ、トップページを公開
- Nuxt 3プロジェクト作成(
npx nuxi init) - Vuetify 3セットアップ
- Cloudflare Pagesデプロイ設定
- トップページ作成(Udemy/Kindleリンクカード)
- 基本レイアウト・ナビゲーション
技術スタック:
Nuxt 3.x
├── Vuetify 3(vuetify-nuxt-module)
├── Pinia(状態管理)
└── Cloudflare Pages(ホスティング)
nuxt.config.ts:
export default defineNuxtConfig({
ssr: true,
nitro: {
preset: 'cloudflare-pages'
},
modules: [
'vuetify-nuxt-module',
'@pinia/nuxt'
]
})
Phase 2: 静的コンテンツ移植
目的: 主要な講義テキストを移植
優先順位:
/lessons/bookkeeping/- 日商簿記3級(最もアクセスが多いはず)/lessons/excel-shortcuts/- Excelショートカット/lessons/financial-statements/- 財務3表/lessons/intro-to-accounting/- 会計・簿記入門
移植方法:
- 既存の.vueファイルからコンテンツ(データ)を抽出
- 新しいコンポーネント構造で再実装
- UIはVuetify 3で刷新
Phase 3: 問題集・テスト機能
目的: 復習アプリ・問題集機能を移植
-
/sampleTest/- サンプルテスト -
/workbook/boki3- 仕訳問題
認証について: 現状のFirebase認証は実質未使用(コードはあるがルート保護なし)。新規プロジェクトでは以下の選択肢がある:
- 認証なしで公開 - 現状と同じ(履歴保存なし)
- 認証を新規実装 - Firebase v9+ or Cloudflare Access
- 機能を廃止 - 利用者が少なければ
利用状況を確認してから判断。
URL戦略
方針: 主要URLは維持、細かいのは整理
# 維持するURL
/lessons/bookkeeping/... → そのまま
/lessons/excel-shortcuts/ → そのまま
# 整理するURL(リダイレクト設定)
/lessons/bookkeeping/chapter01/00-bspl → /boki3/1/bspl(短縮案)
Cloudflareリダイレクト設定
public/_redirects:
# 旧URL → 新URL
/old-path /new-path 301
旧サイトからの切り替え
Step 1: 新サイトを別ドメインで公開
新: cockpit.pages.dev(Cloudflare)
旧: app.eurekapu.com(Heroku)← まだ稼働
Step 2: 動作確認後、ドメイン切り替え
新: app.eurekapu.com(Cloudflare)
旧: 停止
Step 3: Heroku削除
月額$7の節約完了。
費用比較
| 項目 | Heroku | Cloudflare Pages |
|---|---|---|
| 月額費用 | $7 (Basic Dyno) | $0 |
| 帯域幅 | 制限なし | 無料枠: 無制限 |
| ビルド時間 | - | 500分/月 |
| 同時ビルド | 1 | 1 |
トラブルシューティング
ビルドエラー: Node.js バージョン
Cloudflare Pagesのデフォルトは古いNode.jsの場合がある。環境変数で指定:
NODE_VERSION=18
404エラー(SPA/SSRルーティング)
Nuxtのルーティングが動作しない場合、_routes.json の設定を確認。または、Cloudflare Pages Functions を使っているか確認。
API呼び出しのCORSエラー
Cloudflareのドメインからのリクエストを許可するよう、APIサーバー側のCORS設定を更新。
工数見積もり(新規プロジェクト方式)
| フェーズ | 期間 | 備考 |
|---|---|---|
| Phase 1: 基盤 + トップページ | 1-2週間 | 最小構成で公開 |
| Phase 2: 静的コンテンツ | 2-4週間 | 優先度の高いものから |
| Phase 3: 問題集・テスト | 1-2週間 | 認証なしなら簡単 |
| 合計 | 4-8週間 |
※ Firebase認証が実質未使用のため、認証基盤の移行作業は不要
移植しないもの(廃止候補)
調査で見つかった、おそらく不要なコンテンツ:
pages/testPage/- テスト用components/test/- テスト用コンポーネントstore/testtest.js,store/hoge-module.js- 未使用ストアpages/tbd/,pages/tbd02/- 未完成コンテンツ
次のアクション
- 新規Nuxt 3プロジェクト作成
- Cloudflare Pagesデプロイ確認
- トップページ(リンクカード)実装
- 優先度の高い講義テキストを選定
CSSフレームワークの検討: Vuetify vs Tailwind
結論: Vuetify 3 を採用
Tailwind CSS への移行も検討したが、Vuetify 3 を採用することに決定。
比較検討
| 項目 | Vuetify 3 | Tailwind CSS |
|---|---|---|
| 性質 | コンポーネントライブラリ | CSSユーティリティ |
| フォーム | <v-text-field> で完結 | 自作 or ライブラリ追加 |
| ダイアログ | <v-dialog> | Headless UI等が必要 |
| テーブル | <v-data-table> | 自作 |
| カード | <v-card> | div + Tailwindクラス |
Vuetify 3 を選んだ理由
- 問題集・テスト機能との相性
- フォーム入力、バリデーション、正誤判定のUIが必要
- Vuetifyならコンポーネントが揃っている
- 新規プロジェクト方式のメリット
- Vuetify 2→3 の互換性問題は既存コードを引きずらないので軽微
- 旧プロジェクトの構造を参考にしつつ、クリーンに実装可能
- 開発効率
- UIコンポーネントを自作する必要がない
- 定型的なコードで速く書ける
Tailwind が向いているケース(参考)
- マーケティングサイト、LP(見た目重視、機能少なめ)
- デザイナーがいて独自デザインを追求したい
- 軽量さが最優先
このプロジェクトは「学習コンテンツ + 問題集」という機能系UIが多いため、Vuetifyの方が適している。