はじめに
Next.jsのFast Refresh(ホットリロード)は、開発効率を大幅に向上させる機能です。しかし、環境や設定によっては正常に動作しないことがあります。本記事では、よくある問題と解決策を解説します。
基本的な確認事項
開発サーバーの確認
# 正しいコマンドで起動しているか確認
npm run dev
# または
pnpm dev
# または
yarn dev
キャッシュのクリア
# .nextディレクトリを削除して再起動
rm -rf .next
npm run dev
# node_modulesも含めてクリーンアップ
rm -rf .next node_modules
npm install
npm run dev
package.jsonの確認
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
}
}
Server/Client Componentの問題
’use client’の位置
// ❌ 間違い:useStateを使っているのにServer Component
import { useState } from 'react';
export default function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
// ✅ 正しい:'use client'を追加
'use client';
import { useState } from 'react';
export default function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
イベントハンドラの問題
// ❌ Server ComponentでonClickを使用
export default function Button() {
return <button onClick={() => console.log('clicked')}>Click</button>;
}
// ✅ Client Componentに分離
// components/ClickButton.tsx
'use client';
export function ClickButton() {
return <button onClick={() => console.log('clicked')}>Click</button>;
}
// app/page.tsx(Server Component)
import { ClickButton } from '@/components/ClickButton';
export default function Page() {
return <ClickButton />;
}
ファイル構造の問題
無限ループの防止
// ❌ レンダリングごとにstateを更新(無限ループ)
'use client';
import { useState, useEffect } from 'react';
export default function Problem() {
const [data, setData] = useState([]);
// これは無限ループを引き起こす可能性がある
setData(fetchData());
return <div>{data.length}</div>;
}
// ✅ useEffectで適切に処理
'use client';
import { useState, useEffect } from 'react';
export default function Fixed() {
const [data, setData] = useState([]);
useEffect(() => {
async function load() {
const result = await fetchData();
setData(result);
}
load();
}, []);
return <div>{data.length}</div>;
}
WSL2環境での問題
プロジェクトの配置場所
# ❌ Windowsドライブマウント(遅い、ファイル監視の問題)
/mnt/c/Users/username/projects/my-app
# ✅ WSL2のLinuxファイルシステム(推奨)
/home/username/projects/my-app
# または
~/projects/my-app
プロジェクトの移動
# WSL2内に移動
mkdir -p ~/projects
cp -r /mnt/c/Users/username/projects/my-app ~/projects/
cd ~/projects/my-app
# 依存関係を再インストール
rm -rf node_modules .next
npm install
npm run dev
ファイル監視の設定
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
// WSL2でファイル変更が検出されない場合
webpack: (config, { dev }) => {
if (dev) {
config.watchOptions = {
poll: 1000, // ポーリング間隔(ms)
aggregateTimeout: 300,
};
}
return config;
},
};
module.exports = nextConfig;
Docker環境での問題
docker-compose.yml設定
# docker-compose.yml
version: '3.8'
services:
app:
build: .
volumes:
- .:/app
- /app/node_modules # node_modulesをホストと分離
- /app/.next # .nextもホストと分離
ports:
- "3000:3000"
environment:
- WATCHPACK_POLLING=true
- CHOKIDAR_USEPOLLING=true
command: npm run dev
Dockerfile
# Dockerfile
FROM node:20-alpine
WORKDIR /app
# 依存関係のインストール
COPY package*.json ./
RUN npm install
# ソースコードのコピー
COPY . .
# 開発サーバー起動
CMD ["npm", "run", "dev"]
next.config.js(Docker用)
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
webpack: (config, { dev }) => {
if (dev) {
config.watchOptions = {
poll: 1000,
aggregateTimeout: 300,
};
}
return config;
},
// Docker環境でのホスト設定
output: 'standalone',
};
module.exports = nextConfig;
Turbopack関連の問題
Turbopackを無効化
{
"scripts": {
"dev": "next dev",
"dev:turbo": "next dev --turbo"
}
}
既知の問題を確認
# Turbopackでエラーが出る場合はWebpackに戻す
npm run dev
# 問題なければTurbopackを使用
npm run dev -- --turbo
大きなファイル/node_modulesの問題
ファイル監視の除外
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
webpack: (config, { dev }) => {
if (dev) {
config.watchOptions = {
ignored: [
'**/node_modules/**',
'**/.git/**',
'**/.next/**',
'**/public/**',
],
};
}
return config;
},
};
module.exports = nextConfig;
inotify制限の増加(Linux/WSL2)
# 現在の制限を確認
cat /proc/sys/fs/inotify/max_user_watches
# 一時的に増加
sudo sysctl fs.inotify.max_user_watches=524288
# 永続化(/etc/sysctl.confに追加)
echo "fs.inotify.max_user_watches=524288" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
エラーログの確認
ブラウザコンソール
// 開発者ツールのコンソールで確認
// Fast Refresh関連のエラーメッセージを探す
ターミナル出力
# 開発サーバーのログを確認
npm run dev 2>&1 | tee dev.log
# 特定のエラーを検索
npm run dev 2>&1 | grep -i "error\|fail\|refresh"
デバッグモード
Next.js詳細ログ
# 詳細なログを有効化
DEBUG=* npm run dev
# Next.js固有のログ
DEBUG=next:* npm run dev
環境変数でデバッグ
# .env.local
NEXT_PRIVATE_DEBUG_CACHE=1
チェックリスト
| 確認項目 | コマンド/確認方法 |
|---|
| キャッシュクリア | rm -rf .next |
| 依存関係の再インストール | rm -rf node_modules && npm install |
| ’use client’の確認 | フック使用コンポーネントに追加 |
| WSL2ファイルシステム | ~/projects/に配置 |
| Docker volumes | node_modules分離 |
| ポーリング有効化 | next.config.jsで設定 |
まとめ
| 環境 | 主な対策 |
|---|
| 一般 | キャッシュクリア、‘use client’確認 |
| WSL2 | Linuxファイルシステムに配置 |
| Docker | ポーリング有効化、volumes設定 |
| 大規模プロジェクト | inotify制限増加、除外パターン設定 |
参考文献