• #Nuxt4
  • #移行計画
  • #簿記
  • #Git LFS
  • #Codex
開発eurekapu-nuxt4アクティブ

簿記3級コンテンツのNuxt 4移行計画

旧プロジェクトのディレクトリを1時間ほど掘り返し、簿記3級コンテンツの全体像をつかんだ。2,338個のSVGをGit LFSに載せ、移行計画のドラフトをCodexにレビューさせてファイル名の推定ミスを潰した。

背景

簿記3級のコンテンツは、Nuxt 2 + Vuetify 2で構築した旧プロジェクト(cockpit-nuxt-vuetify)に載っている。このコンテンツをNuxt 4ベースの新プロジェクト(eurekapu-nuxt4)に移行する計画を立てる必要があった。

移行対象は教科書(テキスト)と問題集の2種類。テキストはVueコンポーネントで構成されたスライド形式、問題集はJSON駆動のクイズ形式で、それぞれ構造が違う。

旧プロジェクトの構造調査

SlideType1コンポーネント

旧プロジェクトを開いて最初に目に止まったのが SlideType1 コンポーネントだった。2カラムレイアウトで、左にテキスト、右にSVG画像を配置する構造になっている。

<!-- 旧プロジェクトのSlideType1(簡略化) -->
<template>
  <v-row>
    <v-col cols="6">
      <slot name="text" />
    </v-col>
    <v-col cols="6">
      <img :src="svgPath" />
    </v-col>
  </v-row>
</template>

Vuetifyの v-row / v-col に依存しているため、そのままでは持ってこられない。ただ、レイアウト自体はCSSグリッドかFlexboxで再現できるので、コンポーネントの置き換えは単純な作業になりそうだ。

プラグインによるストア管理

もうひとつ見つけたのが、プラグインで注入されるストア管理の仕組み。目次の生成と「次へ」ボタンによるコンテンツ間の移動を制御している。

旧プロジェクトではVuexストアにスライド一覧を持たせ、プラグインが各ページにナビゲーション機能を注入していた。Nuxt 4ではVuexの代わりにPiniaかcomposableで同等の機能を実装することになる。

具体的には以下の機能を移植する必要がある:

  • 目次の自動生成: スライド一覧からツリー構造の目次を構築
  • 前後ナビゲーション: 「次へ」「前へ」ボタンでスライド間を移動
  • 進捗管理: どこまで読んだかの状態保持

コンテンツのファイル構成

旧プロジェクトのコンテンツは以下の構成だった:

content/
  bookkeeping-3/
    textbook/
      chapter-01/
        slide-001.vue   # 各スライドがVueコンポーネント
        slide-002.vue
        ...
      chapter-02/
        ...
    workbook/
      exercises.json    # 問題データ
    assets/
      svg/              # 2,338個のSVGファイル(169MB)

スライドの総数は数百ページ。各スライドが独立したVueファイルで、SlideType1〜数種類のレイアウトコンポーネントを使い分けている。

Codexレビューによる計画の精査

移行計画のドラフトを書いた後、Codexにレビューを依頼した。

codex exec -m gpt-5.3-codex "このプランをレビューして。瑣末な点へのクソリプはしないで。致命的な点だけ指摘して: memo/2026-03-12/bookkeeping-migration-plan.md"

Codexが指摘したのは、旧プロジェクトのファイル名の推定ミスだった。計画書にはディレクトリ名やファイル名を記憶ベースで書いていたが、実際に旧リポジトリを確認すると一部が違っていた。具体的には:

  • コンポーネント名の大文字/小文字の違い
  • ディレクトリ階層の推定ミス(1階層深かった)

Codexの指摘を受けて旧リポジトリを再確認し、正確なパスに修正した。推定で書いたパスをそのまま計画に残すと、実装時に「ファイルがない」で手が止まるので、この段階で潰せたのは助かった。

Git LFSによるSVG管理

2,338個のSVG問題

簿記コンテンツのSVGファイルは合計2,338個、169MBに達する。これをそのままGitリポジトリに入れると、cloneやfetchのたびに全ファイルをダウンロードすることになる。

Git LFSを導入してSVGファイルをLFS管理下に置いた。

# Git LFSのセットアップ
git lfs install
git lfs track "*.svg"

# .gitattributes に追記される
# *.svg filter=lfs diff=lfs merge=lfs -text

# SVGファイルを追加してプッシュ
git add .gitattributes
git add content/bookkeeping-3/assets/svg/
git commit -m "feat: add bookkeeping SVG assets with Git LFS tracking"
git push

プッシュ時にLFSのアップロードが走り、169MB分のSVGがLFSストレージに転送された。通常のGitオブジェクトにはポインタファイル(約130バイト)だけが残るため、リポジトリ本体のサイズは膨らまない。

LFS導入時の注意点

  • .gitattributes のコミットを先にやらないと、既にステージングされたファイルがLFS管理にならない
  • 既存のコミット履歴にSVGが含まれている場合は git lfs migrate が必要(今回は新規追加なので不要だった)

移行計画の概要

策定した移行計画のステップ:

  1. SlideType1〜N のNuxt 4版コンポーネント作成 - Vuetifyグリッドの代わりにCSSグリッドを使う
  2. ナビゲーション用composableの実装 - 目次生成・前後移動・進捗管理
  3. VueスライドのMDC変換を検討 - 各スライドをMDCファイルに変換できるか調査(できなければVueコンポーネントのまま移植)
  4. 問題集のJSON→Nuxt Content連携 - クイズUIコンポーネントの新規作成
  5. SVGアセットの配信最適化 - Cloudflare Pages上でのキャッシュ戦略

学びメモ

  • Codexのレビューで「ファイル名が実在するか確認したか?」と突かれて、推定ベースの計画書のリスクを思い知った。手を動かして旧リポジトリの ls を叩いてから書くべきだった
  • Git LFSは「先に .gitattributes をコミット、次にファイルを追加」の順序を守らないとハマる。順序を逆にすると通常のGitオブジェクトとして記録され、後からLFSに移行するのが面倒になる
  • 旧プロジェクトのプラグイン注入パターンは、Nuxt 4ではcomposableに1対1で置き換えられそう。Vuexストアの状態管理も useState か Pinia で素直に移行できる見込み

次にやること

  • SlideType1コンポーネントのNuxt 4版プロトタイプを作る
  • 旧プロジェクトのスライド1章分を実際に変換して、工数を見積もる
  • ナビゲーションcomposableの設計を固める