🛡️

Next.js依存関係アップデート運用:緊急パッチを事故らせない手順(検証→ロールバック含む)

に公開

npm audit で Critical が出たからアップデートしなきゃ」
「Next.js の新機能を使いたいから上げよう」

そう思って npm update した直後、本番環境で "500 Internal Server Error" が発生する。
誰もが一度は通る道ですが、これが深夜の緊急対応だったら笑えません。

特に Next.js は進化が早く、依存パッケージ(React, Webpack/Turbopack, ESLint 関連など)の相性問題も発生しやすいフレームワークです。
本記事では、「事故らない」 ための堅実なアップデート運用フローと、万が一の時のロールバック手順をまとめます。

1. 原則:アップデートは「機能開発」と同じ重みを持つ

「依存関係の更新なんてコマンド一発でしょ?」と考えていると痛い目を見ます。
アップデートは 「全機能に影響を与える可能性のある変更」 です。新機能追加よりも影響範囲が広いことを認識しましょう。

推奨される運用ポリシー

  • 定期アップデート: 週 1〜月 1 で Renovate/Dependabot を回し、差分を小さく保つ。
  • 緊急パッチ: セキュリティ Fix は即時対応するが、検証フローは飛ばさない。
  • メジャーアップデート: 別タスクとして切り出し、工数を確保する(Next.js 14 -> 15 など)。

2. 安全なアップデート手順(Workflow)

以下の 5 ステップを遵守することで、事故率を限りなくゼロに近づけます。

Step 1: Changelog の確認

漫然とコマンドを叩く前に、何が変わるのかを確認します。特に BREAKING CHANGE の文字を探してください。

# 現在のバージョンと最新版を確認
npm outdated

Next.js の場合、公式のリリースノートGitHub Releases を必ずチェックします。

Step 2: アップデートの実行と Codemod

Next.js には、破壊的変更を自動修正してくれる Codemod が用意されていることがあります。

# 通常のアップデート
npm install next@latest react@latest react-dom@latest

# メジャーアップデート時は codemod があるか確認
# 例: Image コンポーネントの移行など
npx @next/codemod <transform> <path>

Step 3: ローカル検証(Build & Lint)

dev で動いたからヨシ!」は危険です。
Next.js の開発モード(next dev)と本番ビルド(next build)では、挙動が異なることがあります(特にサーバーコンポーネントや環境変数の扱い)。

必ず本番ビルドを通してください。

# キャッシュを削除してクリーンな状態でテスト
rm -rf .next
npm run build

# 型チェックとLintも忘れずに
npm run type-check # tsc --noEmit
npm run lint

Step 4: プレビュー環境での E2E テスト

Vercel や Cloudflare Pages などを使っている場合、Pull Request ごとにプレビュー環境が立ち上がります。
ここで 「クリティカルパス(会員登録、決済、ログイン)」 だけでも E2E テスト(Playwright/Cypress)を自動実行させると安心です。

人間が目視確認する場合も、このプレビュー環境で行います。

Step 5: カナリアリリース(段階的リリース)

いきなり全ユーザーに適用するのではなく、トラフィックの 10% だけに新バージョンを流す手法です。
Vercel などのプラットフォームでは標準機能として提供されています。

エラー監視ツール(Sentry / Datadog)を睨みながら、エラーレートが上がらなければ 100% 適用します。


3. 緊急時のロールバック手順

どれだけ検証しても、バグる時はバグります。
その時重要なのは、「原因究明する前に、まず戻す」 ことです。

Vercel / Netlify などの場合

これらのプラットフォームは 「Instant Rollback」 機能を持っています。
Web 管理画面から「昨日のデプロイ」を選んで「Redeploy / Rollback」ボタンを押すだけです。ビルド不要で、数秒で切り替わります。

コンテナ(Docker / ECS / K8s)の場合

タグ運用が重要になります。

  1. デプロイ時は app:v1.0.1 のようにバージョンをタグ付けする。
  2. 異常発生時は、マニフェストファイルのイメージタグを app:v1.0.0(前回正常分)に戻して kubectl apply する。

latest タグを使わない」 のが鉄則です。latest だと、どれが「さっきまで動いていたバージョン」なのか分からなくなります。


4. Next.js 特有のハマりポイント

package-lock.json の不整合

複数人で開発しているとロックファイルが競合しがちです。
npm ci(ロックファイルのみからインストール)を使って、環境差異をなくしましよう。

# 確実なインストールのために
rm -rf node_modules
npm ci

キャッシュの悪戯

Next.js の強力なキャッシュ機能(Data Cache / Full Route Cache)が、アップデート後に悪さをすることがあります。
デプロイ時にキャッシュをパージする設定を確認するか、Revalidation (ISR) が正しく機能しているか確認してください。


まとめ

  1. アップデートは「開発」。工数をかけて検証する。
  2. next build が通ることを信じるな。E2E とプレビュー環境を見る。
  3. ロールバックの手順を確立しておく。原因調査はサイトを復旧させてから。

「最新版に追従し続ける」ことは、セキュリティ面でもパフォーマンス面でも最大の防御になります。
恐れずに、しかし慎重にアップデート運用を回していきましょう。

Discussion