開発eurekapu-nuxt4

はじめに

ローカルでレッスンページを開き直したら、簿記3級スライドのパンクズにはpathが抜けていてリンクが切れていた。会計入門はEurekapu / 講義ノート / 会計入門と4階層、case100ノートは3階層、cockpitは独自レイアウトでLangSwitcherを抱え込んでいる。同じプロジェクトの中でパンクズの構造が10通りに分岐していた。

最初は「壊れている1ページだけ直そう」と思ったが、画面を行き来するうちに <nav> のマークアップが各ファイルにべた書きされているのが見え始め、共通化に踏み切った。

何をやったか

1. まずB修正:簿記3級スライドのpath追加

簿記3級スライドのパンクズだけ<NuxtLink>toが空になっていてクリックしても遷移しなかった。共通化の前に、まずこのバグだけ直してコミットした。

2. 共通コンポーネント LessonBreadcrumb.vue を作成

10箇所のレイアウトを順に置換した:

  • bookkeeping-miller(簿記3級スライドのMillerレイアウト)
  • note(会計入門ノート)
  • case100/NoteLayout
  • case100/index
  • cockpit-00-summary(i18n + LangSwitcher を保持)
  • cockpit-01-foundation(4階層パンクズ)
  • cashflow-statement/reference/index
  • consolidated-accounting/index
  • steps
  • bookkeeping

cockpit系はLangSwitcherを右端に置いている関係でslotを切り、本文側のパンクズだけ共通化した。

<!-- LessonBreadcrumb.vue(核心のみ) -->
<template>
  <nav class="lesson-breadcrumb">
    <NuxtLink to="/">Eurekapu</NuxtLink>
    <span>/</span>
    <template v-for="(item, i) in items" :key="i">
      <NuxtLink v-if="item.path" :to="item.path">{{ item.label }}</NuxtLink>
      <span v-else>{{ item.label }}</span>
      <span v-if="i < items.length - 1">/</span>
    </template>
    <slot name="trailing" />
  </nav>
</template>

items を配列で受け取り、最後尾を <slot name="trailing" /> にしておくと、cockpitのLangSwitcherを差し込める。

3. case100ノート130ファイルを一括変換

case100ノートは1論点1ファイル、合計130ファイル。topic-1配下も同じ構造で、画面を開いてVS Codeで <nav class="breadcrumb"> を130回書き換えるのは現実的ではなかった。

スクリプトを書いて流した:

// 既存のべた書きパンクズを <LessonBreadcrumb :items="..." /> に置換
const files = await glob('content/case100/**/*.vue')
for (const file of files) {
  const src = await fs.readFile(file, 'utf8')
  const next = src.replace(NAV_REGEX, (_, title) =>
    `<LessonBreadcrumb :items="[{ label: '講義ノート', path: '/case100' }, { label: '${title}' }]" />`
  )
  await fs.writeFile(file, next)
}

130ファイルが10秒で書き変わった。derivativesディレクトリも同じ正規表現で当たるか確認したら、こちらは別レイアウトを使っていたので対象外と判定して除外した。

4. 別セッションのステージング衝突でやり直し

スクリプトを流したあと git status を見たら、別セッションで作業していた変更がステージング済みになっていた。git stash で退避してから差分を再確認し、自分の担当分のみgit addして 5bbe9bb でコミットした。「全部 git add . で済ませる」と他人の作業を巻き込むので、ファイル指定で足した。

ブラウザ確認

dev serverを立ち上げて各レイアウトを開いた:

  • Eurekapu / 講義ノート / 会計入門 — 3階層、リンクが効く
  • Eurekapu / 講義ノート / 簿記3級pathが入って簿記3級トップへ遷移
  • Eurekapu / 講義ノート / cockpit / 第1章 基礎 — 4階層、LangSwitcherが右端に残った
  • Eurekapu / 講義ノート / case100 / 論点42 のれんの償却 — 130ファイル全てでパンクズが表示

試行錯誤メモ

  • 最初は「該当ファイルだけ手で直す」案で進めたが、case100の中身を開いた瞬間に130ファイルあると気づいて方針転換した。1ファイル30秒でも65分かかる
  • スクリプト化したら10秒で終わった。手動で「あっこのファイル忘れてた」が発生する余地も消えた
  • 別セッションのステージング衝突は予想外で、git status を作業前と作業後で2回見るルールにした方がいい

学び

共通コンポーネントに切り出すかどうかは、画面の数ではなくマークアップの重複回数で決まる。今回は10箇所で同じ <nav> を書いていたので、1箇所直すたびに10箇所が同期する世界に変わった。次にcockpit-02やcase100-topic-2が増えても、<LessonBreadcrumb :items="..." /> を1行書けば終わる。

スクリプトで一括変換する判断は、ファイル数が3桁を超えた瞬間に自動的に発火させていい。手で当てる方が早いと感じる脳の錯覚は、30ファイルあたりで逆転する。