Nuxt.jsで作成したアプリケーションをVSCodeとFirefoxでデバッグする

Nuxt.jsで作成したアプリケーションをVSCodeでデバッグする方法のメモ。ググるとChromeのは出てくるが、Firefoxでやる場合の設定はあまり出てこなかったので備忘録代わりに（と言っても、Chromeの場合とあまり変わらないが）。

# 環境
* Ubuntu 18.04.5 LTS
  * カーネル：5.3.0-23-generic #25~18.04.2-Ubuntu SMP Thu Nov 21 22:27:50 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
* Visual Studio Code: 1.56.0
* Node.js: 15.12.0
* Nuxt.js: 2.12.1

# 手順
## Debugger for Firefoxのインストール
VSCodeの拡張機能である[Debugger for Firefox - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=firefox-devtools.vscode-firefox-debug)をインストールする。VSCodeがFirefox上で動くアプリケーションや拡張機能をデバッグするためのアドオンらしい。

## ソースマップの出力
ソースマップとは、トランスパイル前後のソースコードの対応を取るための情報らしい。以下のようにして、開発環境のみ、この情報を出力するようにする。

```typescript:nuxt.config.ts
// （中略）
  build: {
    extend(config: any, ctx: any) {
      if (ctx.isDev) {
        config.devtool = 'eval-source-map'
      }
    }
  },
// （中略）
```

ソースマップにはパフォーマンスやクオリティの異なるいくつかのバリエーションがある。詳細は[Devtool | webpack](https://webpack.js.org/configuration/devtool/)を参照のこと。なお、以下の設定では、

>Recommended choice for development builds with high quality SourceMaps.

とのcommentに従い、`eval-source-map`を選択している。

開発環境であるかどうかは、コンテキスト情報を格納したオブジェクト`ctx`のキー`isDev`を参照すれば分かる（参考：[コンテキスト - NuxtJS](https://ja.nuxtjs.org/docs/2.x/internals-glossary/context/#isdev)）。また、`ctx`にはbooleanのキー`isClient`や`isServer`があり、アプリケーションがクライアントサイドなのかサーバサイドなのかも判別できるようだ（参考：[build プロパティ - NuxtJS](https://ja.nuxtjs.org/docs/2.x/configuration-glossary/configuration-build/#extend)）。

## デバッグ用コマンドの追加
アプリケーションの起動時に、デバッグクライアントも立ち上げる必要がある。これを実現するためには、`--inspect`オプションを付けてnodeを起動すれば良い。

```typescript:package.json
// （中略）
  "scripts": {
    "debug": "node --inspect node_modules/.bin/nuxt-ts"
  },
// （中略）
```

なお、デフォルトでは、デバッグクライアントは`127.0.0.1:9229`で待機する（参考：[デバッグ - 入門 | Node.js](https://nodejs.org/ja/docs/guides/debugging-getting-started/)）。

# VSCodeへのアプリケーションとブラウザを起動する設定の追加
.vscode/launch.jsonを作成し、以下のように記述する。

```javascript:.vscode/launch.json
{
    "configurations": [  
        {
            "type": "node",
            "name": "Launch via npm",  // VSCode上に表示される名前。任意
            "request": "launch",
            "runtimeExecutable": "npm",
            "runtimeArgs": [
                "run",
                "debug"  // package.jsonに記載したスクリプト名
            ],
            "cwd": "${workspaceFolder}",
            "port": 9229,  // デバッグクライアントのポートを指定する
            "sourceMaps": true  // ソースマップを利用することを表す
        },
        {
            "type": "firefox",
            "name": "Launch Firefox",
            "request": "launch",
            "reAttach": true,
            "profile": "default",  // 使用するプロファイル名を指定する
            "keepProfileChanges": true,  // 既存のプロファイルをそのまま使う。falseにすると、profileで指定したプロファイルをコピーして使う
            "url": "http://localhost:3000",  // アクセスするURL. 今回は、nodeアプリケーションがlocalhost:3000で上がる前提になっている
            "webRoot": "${workspaceFolder}",
            "pathMappings": [
                {
                    "url": "webpack:///app",
                    "path": "${workspaceFolder}/app"
                }
            ]
        }
    ],
    "compounds": [
        {
            "name": "Full-stack",
            "configurations": ["Launch via npm", "Launch Firefox"]
        }
    ]
}
```

`configurations`には、プログラムやデバッガを起動するプロファイルを書く。ここでは、nodeを起動するプロファイル`Launch via npm`と、Firefoxを起動するプロファイル`Launch Firefox`を設定している。これらのプロファイル名`name`は任意であり、識別しやすい名前を付けておく。

`Launch via npm`では、コマンド`npm run debug`でnodeを起動する（`runtimeExecutable`を引数`runtimeArgs`で実行）。

`Launch Firefox`では、Firefoxを起動する。`request`に`launch`を指定すると、ブラウザを新規に起動する。`attach`とすると、既存のブラウザにアタッチしようとする。ただし、この場合は、ブラウザにアタッチできるように予め設定が必要。詳細は[Debugger for Firefox - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=firefox-devtools.vscode-firefox-debug)の"Getting Started" -> "attach"を参照されたい。

また、`profile`にプロファイル名を指定すると、ブラウザの起動時に指定したプロファイルを読み込ませることができる。プロファイル名を確認するには、ブラウザのアドレスバーに`about:profiles`を打ち込む（参考：[reactjs - How to preserve extensions in Firefox with VSCode and request Launch - Stack Overflow](https://stackoverflow.com/questions/59814980/how-to-preserve-extensions-in-firefox-with-vscode-and-request-launch)）。ブラウザの拡張機能、例えばVue.js devtoolsなどを併用する場合は、普段使っているプロファイルを読み込ませるのが便利。

`compounds`には、`configurations`で設定した複数のプロファイルを同時に起動する設定を記載できる。ここでは、アプリケーションの起動 (`Launch via npm`) とブラウザの起動 (`Launch Firefox`) を同時に行うプロファイル `Full-stack` を作成している。

## 起動
VSCodeのメニュー"View" -> "Run" (Ctrl+Shift+D) を開くと、先ほど`configration`や`compounds`として登録した起動プロファイルがプルダウンリストで表示されるので、`Full-stack`を選んで"Start Debugging"（再生ボタン）をクリックすると、nodeアプリケーションとブラウザ (Firefox) が立ち上がる。

# 参考にしたページ
* [Visual Studio CodeでNuxt.jsにデバッガをかける|sitateru tech blog](https://tech-blog.sitateru.com/2018/11/visual-studio-codenuxtjs.html)
* [Debugging Nuxt.js with VS Code – Sweetcode.io](https://sweetcode.io/debugging-nuxt-js-vs-code/)