簿記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が必要(今回は新規追加なので不要だった)
移行計画の概要
策定した移行計画のステップ:
- SlideType1〜N のNuxt 4版コンポーネント作成 - Vuetifyグリッドの代わりにCSSグリッドを使う
- ナビゲーション用composableの実装 - 目次生成・前後移動・進捗管理
- VueスライドのMDC変換を検討 - 各スライドをMDCファイルに変換できるか調査(できなければVueコンポーネントのまま移植)
- 問題集のJSON→Nuxt Content連携 - クイズUIコンポーネントの新規作成
- SVGアセットの配信最適化 - Cloudflare Pages上でのキャッシュ戦略
学びメモ
- Codexのレビューで「ファイル名が実在するか確認したか?」と突かれて、推定ベースの計画書のリスクを思い知った。手を動かして旧リポジトリの
lsを叩いてから書くべきだった - Git LFSは「先に
.gitattributesをコミット、次にファイルを追加」の順序を守らないとハマる。順序を逆にすると通常のGitオブジェクトとして記録され、後からLFSに移行するのが面倒になる - 旧プロジェクトのプラグイン注入パターンは、Nuxt 4ではcomposableに1対1で置き換えられそう。Vuexストアの状態管理も
useStateか Pinia で素直に移行できる見込み
次にやること
- SlideType1コンポーネントのNuxt 4版プロトタイプを作る
- 旧プロジェクトのスライド1章分を実際に変換して、工数を見積もる
- ナビゲーションcomposableの設計を固める