Article by: Matt Henderson, Sarah Guthals
デバッグ… それはすべての開発者にとって必要不可欠なスキルです。Next.js を使って動的で高性能なアプリケーションを構築する際、Chrome DevTools や console.log() だけでは対応しきれない場面もあります。またアプリケーションが成長していくにつれて、より効果的で体系的なデバッグ手法が求められるようになります。
今回の記事では Next.js のデバッグワークショップで紹介した実践的なヒントを交えながら、開発段階から本番環境まで役立つデバッグ手法をご紹介します。
今回は Next.js に特化した内容ですが、React アプリのデバッグについてもこちらで紹介しています。ぜひご一読ください。
効果的な Next.js のデバッグツールとテクニック
デバッグはエディタでコードを書きながらローカル環境でテストしている段階から始まります。
まずはそこから解説していきます。そして最終的には、本番環境にデプロイされた後、開発チームではなく実際のユーザーがバグを発見するような場面でのデバッグ方法まで理解できるようになるはずです。
1. React Developer Tools を活用する
Next.js は React を基盤としたフレームワークであり、幸いなことに React Developer Tools を使えば、コンポーネントの階層や props、state を直感的に確認できます。React DevTools を活用すると、以下のようなことが可能になります。
・コンポーネントツリーを視覚的に把握できるため、動的ルーティングやサーバサイドレンダリング(SSR)を使用しても階層構造を理解しやすくなる
・リアルタイムで state や props を解析、編集を行える
・再レンダリングのトラッキングが可能になる
・React Suspenseの遅延読み込みの挙動を可視化できる
デバッグのヒント:React DevTools でハイドレーションエラーを発見する
SSR から CSR への移行時に、props の変化によって微妙なハイドレーションバグが発生することがあります。React DevTools を使えば、コンポーネントが不整合な props で再レンダリングされているかを確認できます。
Next.js デバッグワークショップ(オンデマンド視聴可能)でも頻繁に取り上げられたのが、サーバーサイドレンダリング(SSR)とクライアントサイドレンダリング(CSR)間での props の不整合をデバッグする方法です。
React DevTools を使うことで、ハイドレーション時の props を詳細に確認し、ミスマッチを早期に発見することができます。これにより、アプリのパフォーマンス向上にもつながります。
【例】
2. カスタムエラーページ
コードをすべて自分で書いていても、AI を活用していても、エラーは避けられません。ユーザーが実際の環境でエラーに遭遇したとき、適切なエラーハンドリングができていなければ、混乱を招いたり、信頼を失う原因となります。
そのため、アプリケーションレベルのエラーを処理するカスタムエラーページ(pages/_error.js)を作成することは、簡単かつ効果的な対策の一つです。
getInitialProps を使用すれば、HTTP ステータスコードなどのエラーデータを取得し、ユーザーに適切なメッセージを表示できます。また、エラーが発生した際に、ユーザーをアプリケーション内の別のページに誘導し、可能な限りタスクを継続できるようにするのも有効です。
SSR と CSR の両方で適切にエラーを処理し、カスタムエラーページを導入することで、より詳細なエラー情報を得ることができます。特に、自動エラートラッキングと組み合わせると、さらなる改善につながります。
【例】
3. VSCode での Next.js クライアントサイド & サーバーサイドデバッグ
Next.js のページは、サーバーサイドとクライアントサイドの両方の側面を持っています。
・サーバーサイド:ページ生成を処理
・クライアントサイド:インタラクティブな動作とレンダリングを管理
VSCodeでこれらを効果的にデバッグするには、2つの起動タスクを設定する必要があります。
①サーバーサイドデバッグ:Next.jsのサーバープロセスにアタッチ
②クライアントサイドデバッグ:ブラウザのJavaScriptランタイムにアタッチ
この2つのデバッグタスクを組み合わせることで、Next.jsアプリの動作をより深く理解し、実行フローを把握しながら効率的に問題を特定できます。
サーバーサイドデバッグ
Next.jsのサーバーサイドのロジックは、多くの場合、getServerSideProps メソッド内に記述されており、リクエストごとに実行されます。
これをデバッグするには、以下の手順を実施します。
- プロジェクトのルートディレクトリに .vscode フォルダを作成する(または開く)
- launch.json ファイルを探す(または作成する)
- Next.js のランタイムを runtimeExecutable として指定し、Node.js の起動タスクを設定する
【例】
次に、getServerSideProps メソッドの任意の場所にブレークポイントを設定し、デバッガを起動します。
これにより、サーバーサイドの処理をステップ実行しながら、外部APIなどのデータをリアルタイムで検査できるようになります。
クライアントサイドデバッグ
Next.js のクライアントサイドコードをデバッグするには、以下の手順を実施します。
- Debugger for Chrome 拡張機能をインストールする。
- launch.json に Chrome の起動タスクを追加する
これにより、Next.js アプリ内で動作するクライアントサイドのReactコンポーネントをブラウザ上で直接デバッグできるようになります。
【例】
次に、index.tsx などの Reactコンポーネントにブレークポイントを設定し、VSCode から Chrome を起動します。
コンポーネントの state や props をリアルタイムで確認したり、コードをステップ実行しながら変化を解析するといったデバッグ作業がスムーズに行えるようになります。
Next.js の一般的なエラーの解決方法
Next.js アプリケーションを開発し、そしてデバッグし続ける中で、経験豊富な開発者でさえ日々直面するいくつかの一般的なエラーに遭遇することになるでしょう。
そこで、さまざまな情報源を探し回る手間を省くために、Next.jsのよくあるエラーとその解決方法 をまとめた包括的なガイドを用意しました。こちらでは、エラーが発生する原因と、その具体的な修正方法を解説しています。
特によく報告されるエラーの一例として、以下のようなものがあります。
- Document/Window オブジェクトのエラー
- ミドルウェアのエラー
- API/Slug のエラー
- モジュールのエラー
- CORS エラー(Next API Routes)
もしこのガイドで該当するエラーが見つからない場合は、Sentry Answers の Next.js ハブ もチェックしてみてください。
そこには、さらに多くの Next.js のエラーと、それぞれの解決方法がステップごとに解説されています。
デバッグのしやすさは、アーキテクチャが大きく左右する
AI の進化により、開発者はコードを書く時間を減らし、その分アプリケーションの設計により多くの時間を費やせるようになっています。もし、現在構築しているアプリに最適なアーキテクチャについて考えたことがなければ、今こそ見直すタイミングかもしれません。なぜなら、アーキテクチャの選択は、アプリの拡張性や保守性、そしてデバッグのしやすさに大きな影響を与えるからです。
例えば、Clean Architecture は、Next.js のような複雑なアプリケーションのデバッグに適した設計パターンの一つです。コードを UI、ビジネスロジック、データ の3つの層に分けて整理することで、アプリケーションの無関係な部分に影響を与えることなく、問題を特定して修正できます。このアプローチを採用すると、以下のようなメリットがあります。
・コードの可読性が向上し、保守性が高まる
・UI のデバッグ時に、ビジネスロジックのコードを調べる必要がなくなるため、時間を節約できる
・依存関係が減り、デバッグ作業がスムーズになる
Next.jsのプロジェクトに Clean Architecture を導入することで、デバッグの効率を大幅に向上させることができます。より詳しく知りたい方は、Clean Architecture に関する詳細なワークショップ や Lazar Nikolov氏のYouTube動画 もぜひチェックしてみてください!
Sentry を活用してエラートラッキングを改善し、Next.js アプリのパフォーマンスを最適化する
ここまでに紹介したヒントやツール、テクニックを駆使し、アプリの準備が整い、いよいよ本番環境でユーザーに提供する段階になったとします。
では、ユーザーに高品質で信頼性の高い体験を提供するためには、何が必要でしょうか。その答えの一つが Sentry です。
アプリが実際にリリースされ、世界中のさまざまなデバイスや不安定なネットワーク環境で利用されるようになると、これまで再現できなかった未知の問題が次々と発見されることになります。「自分の環境では動く」は通用しません。
Sentry はデバッグのしやすさに重点を置いたパフォーマンス監視プラットフォーム で、根本的な原因を特定し、できるだけ素早く修正できるように設計されています。
これにより、デバッグに時間を取られず、アプリ開発に集中することができるようになります。短いデモを見たい方は、Next.js のeコマースサイトを例にしたワークショップをチェックしてみてください。
それでは、Next.js のデバッグに役立つ Sentry の重要な5つの機能を詳しくご紹介します。
1. Sentry を活用した API エラーのトレースとデバッグ
Next.js アプリケーションのデバッグにおいて、大きな課題の一つが API の問題を診断することです。Sentry のリアルタイム API 監視機能を使用することで、サーバーログで見逃される可能性のあるエラーを確実に発見することができます。
デバッグのヒント: Sentry の Breadcrumbs を活用してレースコンディション(複数の処理が同時実行された時、競合によって予期しない状態によって起きる問題)を特定する。
リアルタイムデモ中に、解決が難しい 500 エラーを追跡しました。Sentry の Breadcrumbs を使用することで、getServerSideProps のフェッチ処理内で発生していたレースコンディションを特定できました。
getServerSideProps 内でのエラーハンドリングの例は以下の通りです。
2. パフォーマンスの問題もバグであり、デバッグすべき対象
Next.js においてパフォーマンスは非常に重要であり、特にサーバーサイドレンダリング(SSR)を使用している場合は注意が必要です。Sentry の Performance Insights を活用すると、遅いデータベースクエリ、API コール、レンダリングのボトルネックを追跡し、アプリのパフォーマンスを詳細に把握できます。
デバッグのヒント:Sentry の分散トレースを活用してパフォーマンスのボトルネックを特定する。
Sentry のパフォーマンストレースを使用し、SSR 環境で発生していた外部 API コールの遅延を特定しました。リクエストのタイミングをウォーターフォールビューで可視化することで、最適化すべきポイントを見つけることができました。
設定を始めるには、アプリ内で Sentry を初期化し、トレースを有効にします。
Sentry Profiling を使用すると、SSR のページ読み込みや API リクエストのパフォーマンスをスパンで監視できます。
こちらの例は、Sentry が SSR リクエスト中のデータ取得にかかる時間を追跡し、外部 API の遅延やレンダリングの問題を特定可能にします。
Sentry のウォーターフォールビューを使うことで、各処理のパフォーマンスを簡単に確認でき、最適化が必要なポイントを特定できるようになります。
フロントエンドとバックエンドの両方を監視することで、Sentry はパフォーマンスのボトルネックを特定し、解決を支援します。
これにより、Next.js アプリ全体の速度が向上します。詳細については、Sentry を使用して Next.js のパフォーマンスを監視する方法を紹介した記事をご覧ください。
3. Session Replay を活用して、実際のユーザー体験を理解しデバッグする
Sentry の Session Replay は、ユーザーの操作を記録し、再現が難しいバグを特定しやすくします。ユーザーの行動を可視化することで、エラーが発生するまでの流れを正確に把握できるようになります。
デバッグのヒント: Session Replay を活用して、ユーザーが複雑な状態に至る過程を特定する。
Session Replay を使用することで、ユーザーの操作を追跡し、複雑なステート管理のバグを発見しました。セッションを再生することで、ユーザーの入力を確認でき、ログだけでは得られなかった重要なコンテキストを把握することができました。
関係の準備を担当するジョブのセットがあり、プラグインがサポートする各プラットフォームごとに1つずつ設定されます。
Session Replay を有効にするコード例は、以下の通りです。
この設定を行うことで、Sentry は自動的にユーザーセッションを記録・再生し、バグに至るまでの操作をステップごとに確認できるようになります。特に、開発中に再現が難しい UI やステート関連の問題を迅速に発見・対応したい際に役立ちます。
Session Replay をエラーモニタリングやパフォーマンスインサイトと組み合わせることで、Next.js アプリが実際の環境でどのように動作しているかを包括的に把握でき、問題の診断と解決をより迅速に行うことができます。詳細については、Sentry の Session Replay のドキュメントをご覧ください。
4. 分散トレースで複雑な問題を可視化する
分散トレース は、リクエストがフロントエンドからバックエンド、さらには複数のサービスを経由してどのように処理が進のか、追跡するために必要不可欠です。
特に、マイクロサービスアーキテクチャを採用している場合や、サーバーレス環境を利用している場合、分散トレースは問題の根本原因を特定するためのほぼ唯一の有効な手段となることもあります。
幸いなことに、デバッグを重視したプラットフォームである Sentry を活用すれば、分散トレースは簡単に実装できます。
フロントエンド、バックエンド、そしてすべてのサービスに Sentry SDK をインストールすることで、Sentry の分散トレース機能がスパンを自動的に記録し、トレースが困難なエラーやパフォーマンスボトルネックを簡単に特定できるようになります。特に、フロントエンドでの遅延が発生している場合、その原因が実は「データベースクエリが遅かった」というケースは頻繁にあります。
アプリケーション全体のスタックを通じてリクエストをトレースすることで、通常では検出が難しいエラーやパフォーマンスの問題を可視化します。個人開発でも、大規模なチーム開発でも、根本原因を特定するだけでなく、アプリのどの部分に問題があるのかを素早く判断できることは、開発スピードを大幅に向上させることが可能になるのです。
これにより、ログを延々と調査したり、顧客の環境を再現しようと試みるのではなく、より多くの時間をイノベーションに費やせるようになります。
Next.js での分散トレースの設定方法について詳しく知りたい方は、Lazar Nikolov 氏による Next.js の分散トレースに関する 8 部構成の YouTube シリーズ をチェックしてみてください。
5. Sentry の Next.js への統合は簡単
Sentry を導入すれば、未処理の例外やAPI エラー、パフォーマンスのボトルネックをリアルタイムで検出できることは、すでに理解されているかと思います。
Next.js アプリケーション(特に SSR を利用する場合)に統合すると、Sentry はクライアントサイドとサーバーサイドの両方で、コンテキスト、スタックトレース、パフォーマンス指標を記録します。エラーを発生した API コールやコードの正確な位置を特定できるため、デバッグ時間を大幅に短縮できるうえ、導入も非常に簡単です。
Sentry にサインアップした後は、インストールウィザードを実行するだけでセットアップが完了します。
このウィザードを実行すると、アプリケーションのルートディレクトリに sentry.client.config.js、sentry.edge.config.js、sentry.server.config.js の3つの設定ファイルが作成されます。
開発の初期段階でトレースと Session Replay を設定することを強く推奨します。
これにより、エラーの発生状況やパフォーマンスの問題を早期に把握できるようになります。クライアント設定ファイルは次のようになります。
ファイル名: sentry.client.config.js
ただし、想定される使用状況に応じてサンプリングレートを調整するとよいでしょう。また、ウィザードはサンプルエラーを含むページも作成するため、セットアップが正しく行われたかをすぐに確認できます。
その後のエラーハンドリングも常に簡単です。
処理済みのエラーを記録するには、Sentry の captureException を使用するだけで済みます。
Next.js アプリをデバッグする
Next.js アプリを効率的にデバッグするには、従来のテクニックと高度なエラートラッキングツールを組み合わせることが重要 です。基本を押さえ、よくある問題を理解し、クリーンアーキテクチャで設計し、Sentryを活用することで複雑な Next.js の問題も迅速かつ効果的に解決できるようになります。
Next.js デバッグに関するよくある質問
Next.js のハイドレーションエラーの一般的な原因は?
ハイドレーションエラーは、サーバーでレンダリングされたコンテンツと、クライアント側のコンテンツが異なる場合に発生することが多いです。サーバーサイドとクライアントサイドの状態が一致していることを確認し、React.StrictMode を使用して潜在的な問題を早期に検出しましょう。詳しくはこちらをご覧ください。
Next.js で SSR 固有のエラーをデバッグするには?
Node.js インスペクターを使用して、SSR コードにデバッガをアタッチすると効果的です。本番環境でのデバッグには、Sentry を活用するとSSR固有の例外をキャプチャし、スタックトレースを提供して問題解決をスムーズに進められます。
Next.js のパフォーマンスを監視する最適な方法は?
Sentry の Next.js モニタリングを使うと、遅い API ルート、ページの読み込み時間、サーバーサイドレンダリングのボトルネックを追跡できます。フレームグラフを活用すれば、パフォーマンスの問題を詳細に分析しやすくなります。詳しくはこちらをご覧ください。
IchizokuはSentryと提携し、日本でSentry製品の導入支援、テクニカルサポート、ベストプラクティスの共有を行なっています。Ichizokuが提供するSentryの日本語サイトについてはこちらをご覧ください。またご導入についての相談はこちらのフォームからお気軽にお問い合わせください。