• #nuxt
  • #content
  • #sqlite
  • #file-watch
  • #hmr
開発nuxt-content-docsメモ

Nuxt Content: ファイル監視と自動更新の仕組み

概要

Nuxt Content v3では、マークダウンファイルの追加・編集・削除を自動で検知してSQLiteデータベースに反映します。手動でデータベースを操作する必要はありません。

開発環境での動作(pnpm run dev

1. ファイル監視の仕組み

┌─────────────────────────────┐
│ content/ ディレクトリ         │
│  ├── article1.md            │
│  ├── article2.md            │
│  └── new-article.md  ← 追加 │
└──────────────┬──────────────┘
               │
               │ ① Vite File Watcher が検知
               │    (chokidar 使用)
               ↓
┌─────────────────────────────┐
│ Nuxt Content ビルドプラグイン│
│  @nuxt/content/dist/runtime  │
│  /server/storage/builder     │
└──────────────┬──────────────┘
               │
               │ ② フロントマター解析
               │    (YAML パース)
               ↓
┌─────────────────────────────┐
│ SQLite データベース           │
│  .data/content/contents.sqlite│
│                              │
│  INSERT INTO _content_pages  │
│  VALUES (...)                │
└──────────────┬──────────────┘
               │
               │ ③ HMR イベント送信
               │    (WebSocket 経由)
               ↓
┌─────────────────────────────┐
│ ブラウザ自動リロード          │
│  → 新しい記事が表示される    │
└─────────────────────────────┘

2. 自動更新されるタイミング

操作SQLite の処理ブラウザの動作
新規マークダウン作成INSERT自動リロード
マークダウン編集UPDATE自動リロード
マークダウン削除DELETE自動リロード
フロントマター変更UPDATE自動リロード
ファイル名変更DELETE + INSERT自動リロード

3. 実際の動作確認

手順:

  1. 開発サーバーを起動
    cd apps/web
    pnpm run dev
    
  2. 新しいマークダウンファイルを追加
    # 例: content/test-article.md
    ---
    title: テスト記事
    publishedAt: 2025-10-04
    tags: [test, nuxt]
    ---
    
    # テスト記事
    
    これはテストです。
    
  3. ファイルを保存した瞬間に:
    • ターミナルにログが出力される
    • ブラウザが自動リロードする
    • インデックスページに新しい記事が表示される

ログ例:

[@nuxt/content] ✔ Processed 1 file in 25ms
ℹ hmr update /pages/index.vue

4. SQLiteへの反映を確認する方法

開発中のSQLiteデータベースを直接確認できます:

# SQLiteデータベースを開く
sqlite3 .data/content/contents.sqlite

# 全記事を確認
SELECT id, title, publishedAt FROM _content_pages;

# 特定の記事を確認
SELECT * FROM _content_pages WHERE path = '/test-article';

本番環境での動作(Cloudflare Pages)

1. ビルド時の処理

pnpm run build
# または
npx nuxi generate

内部処理:

┌─────────────────────────────┐
│ 1. content/ 内の全ファイル   │
│    を一括読み込み             │
└──────────────┬──────────────┘
               │
               ↓
┌─────────────────────────────┐
│ 2. 全マークダウンをパース     │
│    - フロントマター解析       │
│    - AST 生成                │
└──────────────┬──────────────┘
               │
               ↓
┌─────────────────────────────┐
│ 3. SQLite データベース構築    │
│    - CREATE TABLE            │
│    - INSERT (全記事)         │
└──────────────┬──────────────┘
               │
               ↓
┌─────────────────────────────┐
│ 4. 圧縮ダンプファイル生成     │
│    .nuxt/content/            │
│      database.compressed.mjs │
└──────────────┬──────────────┘
               │
               ↓
┌─────────────────────────────┐
│ 5. 静的ファイルとして配信     │
│    dist/_nuxt/               │
│      database.compressed.mjs │
└─────────────────────────────┘

2. デプロイフロー

  1. ローカルでマークダウンを追加
    # content/new-article.md を作成
    
  2. Gitにコミット&プッシュ
    git add content/new-article.md
    git commit -m "Add new article"
    git push
    
  3. Cloudflare Pagesが自動ビルド
    # GitHub Actions または Cloudflare Pages の設定
    build:
      command: pnpm run build
      output: dist
    
  4. 自動的にSQLiteに取り込まれてデプロイ
    • ビルド時に全マークダウンがデータベース化
    • database.compressed.mjs が生成される
    • 新しい記事が即座に表示される

3. 本番環境の特徴

  • SQLiteは読み取り専用:ランタイムでの更新はなし
  • 全データが静的ファイルdatabase.compressed.mjs として配信
  • ファイル監視なし:デプロイ時に一度だけビルド

よくある質問

Q1: マークダウンを追加したのに反映されない

開発環境の場合:

  1. 開発サーバーが起動しているか確認
    pnpm run dev
    
  2. ファイルが正しい場所にあるか確認
    # OK: content/ 配下
    content/article.md
    
    # NG: content/ 外
    docs/article.md
    
  3. 拡張子が正しいか確認
    // content.config.ts で設定された拡張子
    source: "**/*.{md,mdx}"
    
  4. キャッシュをクリア
    rm -rf .nuxt .data
    pnpm run dev
    

本番環境の場合:

  1. 再ビルド&再デプロイ
    pnpm run build
    pnpm exec wrangler pages deploy dist
    

Q2: フロントマターが反映されない

  1. BOMをチェック
    # BOMがあると YAML パースが失敗する
    head -n 1 content/article.md | od -c
    
  2. YAML構文を確認
    # ✅ 正しい
    ---
    title: タイトル
    tags: [tag1, tag2]
    ---
    
    # ❌ 間違い(インデント不正)
    ---
    title:タイトル
    tags:[tag1,tag2]
    ---
    
  3. スキーマ定義を確認
    // content.config.ts
    publishedAt: z.coerce.date().optional()
    tags: z.array(z.string()).optional()
    

Q3: 削除したファイルが表示され続ける

  1. 開発サーバーを再起動
    # Ctrl+C で停止
    pnpm run dev
    
  2. キャッシュをクリア
    rm -rf .nuxt .data
    pnpm run dev
    
  3. 本番環境では再ビルド
    pnpm run build
    

設定ファイル

nuxt.config.ts

export default defineNuxtConfig({
  modules: ["@nuxt/content"],
  content: {
    documentDriven: true,
    database: {
      type: "sqlite"
    },
    experimental: {
      sqliteConnector: "native"  // Node.js 22.6+ 推奨
    },
    sources: {
      content: {
        driver: "fs",
        base: resolve(__dirname, "content")
      }
    }
  }
})

content.config.ts(任意)

import { defineContentConfig, defineCollection, z } from "@nuxt/content"

export default defineContentConfig({
  collections: {
    pages: defineCollection({
      type: "page",
      source: "**/*.{md,mdx}",
      schema: z.object({
        title: z.string(),
        publishedAt: z.coerce.date().optional(),
        tags: z.array(z.string()).optional()
      })
    })
  }
})

まとめ

✅ 自動で処理されること

  • ✅ マークダウンファイルの検知
  • ✅ フロントマターの解析
  • ✅ SQLiteへのデータ挿入・更新・削除
  • ✅ ブラウザのリロード(開発環境)
  • ✅ ビルド時のデータベース構築(本番環境)

❌ 手動で行う必要があること

  • ❌ SQLiteの操作 → 不要
  • ❌ データベースの初期化 → 不要
  • ❌ ファイル監視の設定 → 不要

結論:マークダウンファイルを追加・編集・削除するだけで、全て自動で反映されます。

参考リンク