Published on

console.logなしでNext.jsをVSCodeでデバッグさせる方法

Authors

VSCode で Next.js のデバッグをできるようにしたら開発のデバッグが超絶楽になったのでその方法について紹介していきたいと思います。

※補足
Next.js vscode debugとかで Google 検索してみると以下のページに引っかかるかと思いますが、Next.js 9 の環境だと動かないので以下のリンクを参考に修正して動作できるようにしました。

https://github.com/microsoft/vscode-recipes/tree/master/Next-js

最終形のコード

コードだけ知りたいという方は.vscode/launch.jsonを作成し、以下のコードをコピペで大丈夫です。
例は src 配下のディレクトリ構成の場合ですが、root 直下に pages がある場合は src を削除してもらえれば動作すると思います。

{
  "version": "0.2.0",
  "configurations": [
    {
      // For server side rendering debug
      "type": "node",
      "request": "launch",
      "name": "Next: Node",
      "runtimeExecutable": "npm",
      "cwd": "${workspaceFolder}/src",
      "runtimeArgs": [
        "run",
        "dev"
      ],
      "port": 9229,
      "console": "integratedTerminal"
    },
    {
      // For client side rendering debug
      "type": "chrome",
      "request": "launch",
      "name": "Next: Chrome",
      "url": "http://localhost:3000”,
      "webRoot": "${workspaceFolder}",
      "sourceMapPathOverrides": {
        "webpack:///./*": "${webRoot}/src/*"
      }
    }
  ]
}

npm run devは以下のコード package.json

“scripts”: {
  dev: “NODE_OPTIONS='--inspect' next src”
}

Next.js のデバッグ方法について

Next.js はサーバーサイドレンダリングのフレームワークなので、サーバー側とクライアント側の両方にデバッグの設定をする必要があります。
Next.js はサーバー側は Node.js で動いているため、初回のレンダリングは Node.js、その後のクライアントのレンダリングはブラウザのデバッグ設定をする必要があります。

初回レンダリング → Node.jsデバッグ
その後のレンダリング → Chrome(ブラウザ)でデバッグ

それでは順番に設定方法を説明していきます。

Node.js (Server side rendering)のデバッグ設定について

ルート直下の.vscode フォルダ配下に(ない人は作成して)launch.json を作成します。
その後以下の Node.js 設定を記載します。

.vscode/launch.json

{
  "version": "0.2.0",
  "configurations": [
    {
      // For server side rendering debug
      "type": "node",
      "request": "launch",
      "name": "Next: Node",
      "runtimeExecutable": "npm",
      "cwd": "${workspaceFolder}/src", // ← /pagesがsrc配下にない人はsrcの指定は不要です
      "runtimeArgs": ["run", "dev"],
      "port": 9229,
      "console": "integratedTerminal" // 内部のターミナルタブで起動します
    }
  ]
}

package.json

“scripts”: {
  dev: “NODE_OPTIONS='--inspect' next src”
}

ここで注目してほしいのはnpm run devの環境変数でNODE_OPTIONS=--inspectを設定している所です。
このオプションは Next.js というよりも Node.js のデバッグ設定をするためのもので、インスペクタを有効にしてあげると Node.js はデバッグクライアントを立ち上げて待機します。 デバッグクライアントはデフォルトで127.0.0.1:9229のホストとポート で待機するため、そこに lanch.json 上で port を指定してあげれば接続できるわけです。 インスペクタについてはNode.js のドキュメントにも記載されています。

実際に動作させてみた例

node_vscode_debug

※補足

  1. runtimeExecutableに node_module から直接 next を指定しているやり方もありますが、package.json 側と設定が異なってしまうのが嫌だったのでnpmで動作させるようにしました。
  2. 本当は lanch.json 内の env でNODE_OPTIONSを指定したかったが、うまく動作しなかったため、このような書き方になっています。ご存知の方がいればコメントいただけると助かります。。

Chrome(ブラウザ)のデバッグ設定について

次にクライアント側のデバッグ方法です。Node.js の設定の下に以下を追加します。

  {
    // For client side rendering debug
    "type": "chrome",
    "request": "launch",
    "name": "Next: Chrome",
    "url": "http://localhost:3000”,
    "webRoot": "${workspaceFolder}",
    "sourceMapPathOverrides": {
      "webpack:///./*": "${webRoot}/src/*"
    }
  }

そもそも Next.js のコードを Chrome 上でデバックする場合には Chrome DevTool のSources>webpack内にあるコードにブレークポイントを貼ればデバッグできます。

webpack chrome_webpack_debug

ここを理解した上で考えてみると Chrome 上にある webpack 内のコードを VSCode と紐付けしてあげれば良いことがわかります。 紐付けを行うのは以下の部分です。

"webRoot": "${workspaceFolder}",
"webpack:///./*": "${webRoot}/src/*"

webRootには${workspaceFolder}を指定して VSCode のワークスペースと紐付けをします。
次にsourceMapPathOverridesで先程デバックで見た Chrome 上の webpack の path と実際にソースが定義されている src 配下のパスを紐付けます。 (src フォルダ構成でない方は${webRoot}/*でいけるはずです)

これでクライアントサイドのデバッグが可能になります。

chrome_vscode_debug

最終的なコード

最終的なコードは以下になります。

.vscode/launch.json

{
  "version": "0.2.0",
  "configurations": [
    {
      // For server side rendering debug
      "type": "node",
      "request": "launch",
      "name": "Next: Node",
      "runtimeExecutable": "npm",
      "cwd": "${workspaceFolder}/src", // ← /pagesがsrc配下にない人はsrcの指定は不要です
      "runtimeArgs": ["run", "dev"],
      "port": 9229,
      "console": "integratedTerminal" // 内部のターミナルタブで起動します
    }
  ]
}

package.json

“scripts”: {
  dev: “NODE_OPTIONS='--inspect' next src”
}

これでサーバーサイドとクライアントサイド両方のデバッグが可能になりました!
console.log のデバッグをする必要はもうありませんね!