🚀

launch.jsonのすゝめ

2023/07/05に公開

はじめに

ReactやNext.jsでのアプリケーションを
VSCodeで簡単にデバッグできる方法がないか調べていたところ、
launch.json というファイルの存在を知りました。
使ってみると中々に便利だったので、
設定方法などのメモを記事にさせていただきます。

launch.jsonとは?

launch.json はデバッグ時の構成や設定を記述した設定ファイルです。
.vscode フォルダ配下に配置することで、簡単にデバッグを行えるようになります。

https://code.visualstudio.com/Docs/editor/debugging

Reactのデバッグ

Reactのデバッグには、まず .vscode/tasks.json を作成し、
下記のように記述します。

.vscode/tasks.json
{
  "version": "2.0.0",
  "tasks": [
    {
      "type": "shell",
      "command": "yarn run start", // package.jsonの起動したいscript
      "label": "yarn: start", // launch.jsonから呼び出す際の名前
      "detail": "react-scripts start",
      "group": {
        "kind": "test",
        "isDefault": true
      },
      "isBackground": true,
      "problemMatcher": {
        "owner": "custom",
        "pattern": {
          "regexp": "^$"
        },
        "background": {
          "activeOnStart": true,
          "beginsPattern": "Compiling...",
          "endsPattern": "Compiled .*"
        }
      }
    }
  ]
}

"command": "yarn run start" では、package.jsonに記載した

package.json
"scripts": {
  "start": "react-scripts start"
}

を実行しています。
npm のかたは npm run start になります。
また、launch.jsonから呼び出す際の名前として、"label": "yarn: start" を記載しています。

https://code.visualstudio.com/Docs/editor/tasks

次に、.vscode/launch.json を作成し下記のように記述します。

.vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "chrome",
      "request": "launch",
      "preLaunchTask": "yarn: start", // 起動時に実行するタスク(= tasks.jsonの `label`)
      "name": "Launch Chrome against localhost", // Run and Debugタブに表示される設定名
      "url": "http://localhost:3000", // Reactを起動しているurl
      "webRoot": "${workspaceFolder}", // VSCodeのルートディレクトリ
      "sourceMaps": true,
      "sourceMapPathOverrides": {
        "webpack:///./*": "${webRoot}/src/*" // ./src配下にソースコードを記載しているため
      }
    }
  ]
}

上記では、デバッグを開始する際に"preLaunchTask": "yarn: start" (= tasks.jsonのlabel 名)を実行し、
chromeの http://localhost:3000 を開く設定をしています。
後はサイドメニューの Run and Debug で 実行する設定ファイルを選択し、
F5 でデバッグを開始できます!

`sourceMaps`とは?

sourceMapsはJavaScriptの圧縮後のファイルや、TypeScriptのコンパイル後のファイルと
元のソースコードファイルとを紐付けてくれるファイルになり、
これにより、ブラウザが元のソースを再構築し、圧縮やコンパイルされる前の状態=読みやすいファイルでデバッグを行うことができます。

https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/SourceMap
https://firefox-source-docs.mozilla.org/devtools-user/debugger/how_to/use_a_source_map/index.html

Next.jsのデバッグ

次にNext.jsのデバッグでは、下記のように .vscode/launch.json を記述します。

.vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      // サーバーサイド単品のデバッグ
      "name": "Next.js: debug server-side",
      "type": "node-terminal",
      "request": "launch",
      "command": "yarn run dev"
    },
    {
      // クライアントサイド単品のデバッグ
      "name": "Next.js: debug client-side",
      "type": "chrome",
      "request": "launch",
      "url": "http://localhost:3000"
    },
    {
      // サーバーサイドとクライアントサイドの両方をデバッグ
      "name": "Next.js: debug full stack",
      "type": "node-terminal",
      "request": "launch",
      "command": "yarn run dev",
      "serverReadyAction": {
        "pattern": "started server on .+, url: (https?://.+)",
        "uriFormat": "%s",
        "action": "debugWithChrome"
      }
    }
  ]
}

基本的にはReactの記述内容と同じですが、
Next.jsの場合、

  • サーバーサイド(Node.js) 単品でのデバッグ
  • クライアントサイド 単品でのデバッグ
  • サーバーサイド+クライアントサイドのデバッグ

の3パターンが存在しています。
それそれ、Run and Debug で設定ファイル名を選択し F5 でデバッグを開始できます。

https://nextjs-ja-translation-docs.vercel.app/docs/advanced-features/debugging

Nxで管理しているモノレポのデバッグ

最後に、Nx で管理しているモノレポのデバッグ方法について記載します。
筆者の部署ではモノレポ管理に Nxを使用しており、
フロントエンドにNext.js、バックエンドにFastifyのアプリケーションを採用しています。

Nxの構成は、下記のようになっています

.
├── apps
│   ├── my-backend-app
│   ├── my-frontend-app
├── dist
│   ├── apps
│   └── libs
├── libs
├── node_modules
├── nx.json
├── package.json
├── tsconfig.base.json など

Nxで管理しているアプリケーションのデバッグをする際に、
「起動はできるものの、VSCodeのブレークポイントがバインドされない」という事象に引っかかりましたが、
下記の構成でデバッグを行えるようになりました。

まず、上述のように.vscode/tasks.json.vscode/launch.json を作成します。

.vscode/launch.json
{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "debug:backend",
      "type": "shell",
      "command": "nx run <your-backend-app-name>:serve",
      "group": {
        "kind": "build",
        "isDefault": true
      },
      "problemMatcher": []
    }
  ]
}
.vscode/launch.json
{
  "version": "0.2.0",
  "resolveSourceMapLocations": ["${workspaceFolder}/**", "!**/node_modules/**"],
  "configurations": [
    /** フロントエンド(Next.js) */
    {
      "name": "launch frontend", // ★ 起動用の設定名
      "type": "chrome",
      "request": "launch",
      "url": "http://localhost:3000",
      "webRoot": "${workspaceFolder}",
      "sourceMaps": true,
      "sourceMapPathOverrides": {
        "webpack://_N_E/*": "${webRoot}/apps/<your-frontend-app-name>/*",
        "webpack://_N_E/libs/*": "${webRoot}/libs/*",
        "webpack://_N_E/node_modules/*": "${webRoot}/node_modules/*"
      }
    },
    {
      "name": "debug - frontend",
      "type": "node-terminal",
      "request": "launch",
      "command": "cd ../../ && nx run <your-frontend-app-name>:serve",
      "cwd": "${workspaceFolder}/apps/<your-frontend-app-name>",
      "serverReadyAction": {
        "action": "startDebugging",
        "name": "launch frontend", // ★の`name`を指定
        "pattern": "on http://localhost:3000"
      }
    },
    /** バックエンド(Fastify) */
    {
      "name": "debug - backend",
      "port": 9229, // Nxの設定ファイルに記載したデバッグ用のポートを指定
      "preLaunchTask": "debug:backend", // tasks.jsonの`label`を指定
      "request": "attach",
      "skipFiles": ["<node_internals>/**"],
      "type": "node",
      "cwd": "${workspaceFolder}/apps/<your-backend-app-name>"
    }
  ]
}

フロントエンドのアプリケーションは、「Next.jsのデバッグ」同様に、
Chromeを起動しています。
バックエンドのFastify側では、tasks.json でアプリケーションを実行し、
特定のportをリッスンするよう設定します(後述)。
起動したNode.jsのプロセスに対してmy-backend-app をアタッチしています。
※Next.jsのバックエンド側は省略していますが、Fastify同様の手順でデバッグすることができます

次に、.vscode/settings.json に下記を追加します

.vscode/settings.json
{
  // 省略
  "debug.javascript.autoAttachFilter": "always"
}

この設定により、新しく生成されたNode.jsのプロセスでデバッグをするようVSCode側に伝えます。
(上記の設定がない場合、うまくアタッチされませんでした)

https://code.visualstudio.com/docs/nodejs/nodejs-debugging

最後に、./apps/my-backend-app/project.json に、
アプリケーショを起動するportとは別に、デバッグ用にリッスンするportを指定します。

./apps/my-backend-app/project.json
// 省略
  "serve": {
    "executor": "@nrwl/js:node",
      "options": {
        "buildTarget": "my-backend-app:build",
          "port": 9229 // デバッグ用のポートを指定
      }
    },

https://nx.dev/packages/js/executors/node#inspect

これで設定は以上です!
後は同じように設定ファイルを指定して F5 を実行するだけです!

おわりに

launch.json を記述することで、VSCode上で簡単にデバッグが行えるようになりました!
(今まで恥ずかしながらconsole.logしまくっていた、、)

よきデバッグライフを!

参考

https://code.visualstudio.com/Docs/editor/debugging
https://code.visualstudio.com/Docs/editor/tasks
https://code.visualstudio.com/docs/nodejs/nodejs-debugging
https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/SourceMap
https://firefox-source-docs.mozilla.org/devtools-user/debugger/how_to/use_a_source_map/index.html
https://nextjs-ja-translation-docs.vercel.app/docs/advanced-features/debugging
https://code.visualstudio.com/docs/nodejs/nodejs-debugging
https://nx.dev/packages/js/executors/node#inspect
https://blog.nrwl.io/debugging-nx-in-vs-code-cb1dbe9eeeba

https://stackoverflow.com/questions/74122995/debug-next-js-app-with-vscode-in-nx-monorepo
https://nx.dev/packages/js/executors/node#inspect
https://youtu.be/OGV4R0cPRPc
https://youtu.be/uQ7xpHyCBXI

Aidemy Tech Blog

Discussion