• #Nuxt
  • #Vue
  • #移行
  • #Vuetify
  • #Pinia
  • #Cloudflare
開発アクティブ

cockpit-nuxt-vuetify Nuxt 3 移行計画

背景

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

現在のHeroku構成

Heroku ダッシュボード - warm-plains-36011

項目
アプリ名warm-plains-36011
GitHubkeikomatsu/cockpit-nuxt-vuetify
DynoBasic ($7/月)
起動コマンドnpm run start
デプロイ回数199回

なぜ Cloudflare Pages に移行するか

  1. コスト削減: Heroku Basic Dyno $7/月 → Cloudflare Pages 無料
  2. パフォーマンス: Cloudflareのグローバルエッジネットワーク
  3. 簡単なデプロイ: GitHubとの自動連携
  4. 無料SSL: 自動でHTTPS化

移行方針: 新規プロジェクト立ち上げ

既存コードを書き換えるのではなく、新規Nuxt 3プロジェクトをゼロから作成し、必要な機能だけを移植する。

この方式のメリット

  1. 799ページ全部を移行しなくて良い - 必要なものだけ選んで移植
  2. UIを刷新できる - Vuetify 3のデザインをフル活用
  3. 技術的負債を持ち込まない - リファクタリングしながら進められる
  4. 段階的に切り替え可能 - 移行完了したページから順次公開

現状のトップページ構造

トップページ(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: 静的コンテンツ移植

目的: 主要な講義テキストを移植

優先順位:

  1. /lessons/bookkeeping/ - 日商簿記3級(最もアクセスが多いはず)
  2. /lessons/excel-shortcuts/ - Excelショートカット
  3. /lessons/financial-statements/ - 財務3表
  4. /lessons/intro-to-accounting/ - 会計・簿記入門

移植方法:

  • 既存の.vueファイルからコンテンツ(データ)を抽出
  • 新しいコンポーネント構造で再実装
  • UIはVuetify 3で刷新

Phase 3: 問題集・テスト機能

目的: 復習アプリ・問題集機能を移植

  • /sampleTest/ - サンプルテスト
  • /workbook/boki3 - 仕訳問題

認証について: 現状のFirebase認証は実質未使用(コードはあるがルート保護なし)。新規プロジェクトでは以下の選択肢がある:

  1. 認証なしで公開 - 現状と同じ(履歴保存なし)
  2. 認証を新規実装 - Firebase v9+ or Cloudflare Access
  3. 機能を廃止 - 利用者が少なければ

利用状況を確認してから判断。

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の節約完了。

費用比較

項目HerokuCloudflare Pages
月額費用$7 (Basic Dyno)$0
帯域幅制限なし無料枠: 無制限
ビルド時間-500分/月
同時ビルド11

トラブルシューティング

ビルドエラー: 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/ - 未完成コンテンツ

次のアクション

  1. 新規Nuxt 3プロジェクト作成
  2. Cloudflare Pagesデプロイ確認
  3. トップページ(リンクカード)実装
  4. 優先度の高い講義テキストを選定

CSSフレームワークの検討: Vuetify vs Tailwind

結論: Vuetify 3 を採用

Tailwind CSS への移行も検討したが、Vuetify 3 を採用することに決定。

比較検討

項目Vuetify 3Tailwind CSS
性質コンポーネントライブラリCSSユーティリティ
フォーム<v-text-field> で完結自作 or ライブラリ追加
ダイアログ<v-dialog>Headless UI等が必要
テーブル<v-data-table>自作
カード<v-card>div + Tailwindクラス

Vuetify 3 を選んだ理由

  1. 問題集・テスト機能との相性
    • フォーム入力、バリデーション、正誤判定のUIが必要
    • Vuetifyならコンポーネントが揃っている
  2. 新規プロジェクト方式のメリット
    • Vuetify 2→3 の互換性問題は既存コードを引きずらないので軽微
    • 旧プロジェクトの構造を参考にしつつ、クリーンに実装可能
  3. 開発効率
    • UIコンポーネントを自作する必要がない
    • 定型的なコードで速く書ける

Tailwind が向いているケース(参考)

  • マーケティングサイト、LP(見た目重視、機能少なめ)
  • デザイナーがいて独自デザインを追求したい
  • 軽量さが最優先

このプロジェクトは「学習コンテンツ + 問題集」という機能系UIが多いため、Vuetifyの方が適している。

参考リンク