記事一覧へ戻る
TRANSMISSION / MINT読了 6 分

Nuxt 4 におけるアーキテクチャの引き算

コンテンツ中心のサイトに複雑なフロントエンド状態は不要です。ルーティング、SSR、コンテンツクエリを、それぞれ得意な場所へ戻します。

#Nuxt#Vue#アーキテクチャ
複雑なモジュールが明確でコンパクトな Nuxt アプリケーションの中心へ収束していく
アーキテクチャの引き算で境界を明確にする

Nuxt プロジェクトが複雑になる理由は、ビジネスが本当に複雑だからとは限りません。あらゆる将来の可能性を、あまりに早くアーキテクチャへ入れてしまうことがよくあります。

個人ブログは良い調整基準になります。ページ数は限られ、コンテンツ構造は安定し、インタラクションは少数の領域に集中しています。フレームワークの最も価値ある役割は、機能を増やすことではなく、不要な選択肢を削除することだと気づかせてくれます。

デフォルトの SSR から始める

技術記事は検索エンジンに理解される必要があり、低速な回線でも本文をできるだけ早く表示したいものです。Nuxt のデフォルトであるサーバーサイドレンダリングは、その目的に合っています。

export default defineNuxtConfig({
  modules: ['@nuxt/content'],
  nitro: {
    preset: 'cloudflare',
  },
})

サイト全体を SPA に変える必要も、ページごとに別のデータ取得方法を発明する必要もありません。最初のクエリとレンダリングはサーバーで完了し、クライアントが引き継いだ後も同じルーターを使います。

ブラウザ API に依存する小さな領域だけ、局所的に ClientOnly を使えば十分です。一つのクライアントコンポーネントのために、ページ全体のセマンティクスとファーストビューを犠牲にしてはいけません。

コンテンツクエリをページ境界に置く

ホーム、記事一覧、記事詳細では必要なデータ粒度が異なります。クエリは利用するページの近くに置きます。

const { data: posts } = await useAsyncData('latest-posts', () => {
  return queryCollection('posts')
    .where('draft', '=', false)
    .order('publishedAt', 'DESC')
    .limit(6)
    .all()
})

この方法には直接的な利点があります。

  • データが SSR に参加し、onMounted 後に点滅しながら表示されません。
  • クエリキーが明確なので、Nuxt は hydration 時に payload を再利用できます。
  • ページ自身が必要なものを理解し、汎用 store を経由する必要がありません。
  • 下書きの除外と並び順が、本当に関係する場所に現れます。

複数のページが同じ複雑な業務状態を共有するようになったときにだけ、composable や store へ抽出する価値があります。

安定して繰り返すものだけをコンポーネント化する

「再利用できそう」はコンポーネント境界ではありません。本当に安定した繰り返しには、通常、構造、意味、動作が同時に含まれます。

このブログでは記事カードが適切なコンポーネントです。ホームと一覧ページの両方に現れ、メタデータ、タイトル、概要、タグ、遷移動作が固定されています。

一方、ホームの Hero は大きくても、必ずしも五つの小さなコンポーネントへ分割する必要はありません。一つのページにしか現れず、内部要素がまとまって一つの視覚的な物語を作ります。早すぎる分割は、スタイルの関係を複数ファイルへ散らすだけです。

コンポーネントはファイル整理の道具ではなく、独立して理解し再利用できる UI 契約です。

サーバー API のインターフェースを狭く保つ

ログインとコメントは実行時データなので server/api に置きます。各 endpoint は一つの仕事だけを行います。

POST /api/auth/register
POST /api/auth/login
POST /api/auth/logout
GET  /api/auth/session
GET  /api/comments/:post
POST /api/comments/:post

狭いインターフェースは認可規則を確認しやすくします。コメントの読み取りは公開、作成にはセッションが必要、ログアウトはユーザープロフィールに触れず現在のトークンだけを破棄します。

一つの endpoint が読み取り、書き込み、ログイン、形式変換を同時に扱うなら、すでに明確な境界を失っています。

状態を正しい場所へ戻す

Vue のリアクティブな状態は便利ですが、すべての状態を JavaScript に置くべきではありません。

状態最適な場所
現在の記事ルート
検索語ページの ref
タグ絞り込みURL query + ページ状態
ログインユーザーSSR 安全な useState
記事本文Nuxt Content
セッションの真正性サーバー側の D1

状態を正しい場所へ置けば、大量の「同期ロジック」が自然に消えます。ルートを監視して store を修復する必要も、localStorage でログイン状態が信頼できるふりをする必要もなくなります。

引き算は機能を減らすことではない

良いアーキテクチャの引き算は、ユーザーから何も奪いません。むしろ、ユーザーが実際に感じる部分へ複雑さの予算を残します。

  • より明確なタイポグラフィ。
  • より速いファーストビュー。
  • より信頼できるログイン。
  • より快適なモバイル読書。
  • 続けやすい Markdown 執筆フロー。

Nuxt 4 には十分な機能があります。成熟したプロジェクトとは、それらをすべて使うものではなく、今は使わなくてよい機能を知っているものです。

記事はここまで
READER CHANNEL

コメント

00
まだコメントはありません。最初の返信を残してみませんか。