TypeScript + webpack + VS Code + Chromeでブレークポイントデバッグできるようにする

# TypeScript + webpack + VS Code + Chromeでブレークポイントデバッグできるようにする

タイトルの通りの環境でブレークポイントデバッグできるようにするためには、いくつかのハードルを超える必要があります。

どれか1つでも設定が間違っていると、「ブレークポイントで止まらないんだけど！！！！」ってなりますので、なるべく丁寧に、どんな設定が必要なのかを説明します。



# 前提環境

以下の環境はすでに構築済みとします。

- Node.js, Chrome, VS CodeがPCにインストールされている。
- webpack-dev-serverコマンドでPC内にWebサーバーを起動し、Chromeから閲覧できる。
- webpackでTypeScriptをJavaScriptへビルドできる。



# ブレークポイントデバッグできるようにする

## tsconfig.jsonを編集する

`tsconfig.json` を編集し、TypeScriptのソースマップを有効にします。これにより、ビルド前のTypeScriptとビルド後のJavaScriptが関連付けられるようになります。

#### tsconfig.json

```json
{
    "compilerOptions": {
        "sourceMap": true
    }
}
```



## webpack.config.jsを編集する

`webpack.config.js` を編集し、webpackのソースマップを有効にします。これにより、バンドル前後のコードが紐付けられるようになります。

`webpack.dev.config.js` , `webpack.stg.config.js` のように、環境毎に設定ファイルを分けている場合は、 `webpack.debug.config.js` のような設定ファイルを新たに作成するのが良いと思います。以後、 `webpack.debug.config.js` を利用するものとします。

#### webpack.debug.config.js

```javascript
module.exports = {
    mode: "debug".
    devtool: 'inline-source-map',
    devServer: {
    	index: "index.html",
    	port: 9223,
    	historyApiFallback: true,
	}
};
```

ここで、ポートを `9223` と指定しています。これはデバッグ用のポートです。この番号でなければいけないわけではないのですが、 `3000` や `8080` 等を指定してしまうと、通常開発時のポートと混ざって区別がつかなくなる恐れがあるため、避けた方がよいと思います。



## VS CodeにDebugger for Chromeをインストールする

以下の拡張をインストールしましょう。

[Debugger for Chrome](https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome)



## launch.jsonを作成する

`.vscode/launch.json` ファイルを作成します。これはVS Codeのデバッグの設定ファイルです。

#### launch.json

```json
{
    "version": "0.2.0",
 	"configurations": [
        {
            "name": "Launch Chrome",
            "type": "pwa-chrome", // chromeも可
            "request": "launch",
            "url": "http://localhost:9223", // webpack.debug.config.jsで指定したポート番号
            "webRoot": "${workspaceFolder}",
            "sourceMapPathOverrides": {
                "webpack:///./*": "${webRoot}/react/*",
            }
        }
    ]
}
```

#### typeの設定

`"type": "pwa-chrome"` というのは、Chromeをデバッグ起動するデバッガーです。単に `"type": "chrome"` と記述しても動きます。 `pwa-chrome` の方が新しいデバッガーらしいので、とくにこだわりがなければ、そちらを使った方が良さそうです。

詳しくは [What is the pwa-node type launch configuration on VSCode?](https://stackoverflow.com/questions/63442436/what-is-the-pwa-node-type-launch-configuration-on-vscode) をご参照ください。


#### urlの設定

`"url": "http://localhost:9223"` では、 `webpack.debug.config.js` で指定したポート番号を指定します。



#### sourceMapPathOverridesの設定

`sourceMapPathOverrides` は、VS Code内のフォルダーと、ブラウザのソース配置を紐付ける設定です。この設定が非常にわかりずらい！**最難関です！！**

サンプルでは、 `"webpack:///./*": "${webRoot}/react/*"`  となっていますが、これはプロジェクトのフォルダー構造によって変わります。

たとえば、package.jsonを格納しているフォルダーの名前が `react` でなく、 `app` だとか `server` 等であれば、それに合わせて変更する必要があります。

こちらの設定方法は、 [VSCodeのDebugger for ChromeにおけるsourceMapPathOverrides設定メモ](https://qiita.com/beeeyan/items/9b0def365d64d11a4a1c) がわかりやすかったので、ご紹介します。



## settings.jsonを作成する

`.vscode/settings.json` ファイルがなければ作成します。これはVS Codeのエディターの設定ファイルです。

#### settings.json

```json
{
    "debug.javascript.usePreview": false,
    "debug.allowBreakpointsEverywhere": true
}
```



`debug.javascript.usePreview` が `true` だと、ブレークポイントで止まらないことがあるらしいので `false` にします。

`debug.allowBreakpointsEverywhere` が `false` でも、ブレークポイントで止まらないことがあるらしいので `true` にします。



## webpack-dev-serverでデバッグ起動する

以下のコマンドを実行します。

```bash
webpack-dev-server --config webpack.debug.config.js -d
```

デバッグ可能な状態でWebサーバーが起動します。



## VScodeでブレークポイントデバッグしてみる

TypeScriptのお好きな行にブレークポイントを設定してください。

その上で `F5` を押すと、Chromeが起動します。Chromeを操作し、ブレークポイントを設定したコードが実行されると、デバッガーがブレークポイントで止まるはずです！

もし、止まらなかったら、ここまでの設定を見直してください！



# webpack-dev-serverコマンドを自動化する

ブレークポイントデバッグができるようになったのはいいですが、毎回、 `webpack-dev-server` コマンドを叩くのは面倒です。

ここから先は、自動化するための設定を説明します。



## package.jsonを編集する

`package.json` にNPM Scriptを追加します。

#### package.json

```json
{
    "scripts": {
        "debug": "webpack-dev-server --config webpack.debug.config.js -d", // 新規に追加
    }
}
```

これにより、 `npm run debug` を実行すると、 `webpack-dev-server` がデバッグ起動するようになります。



## tasks.jsonを作成する

`.vscode/tasks.json` ファイルを作成します。これは、 `launch.json` の前処理を記述できる設定ファイルです。

#### tasks.json

```json
{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "npm: debug", // タスクの名前。
            "type": "npm",
            "script": "debug",
            "path": "react/", // package.json格納フォルダ
            "isBackground": true,
            "problemMatcher": {
                "owner": "custom",
                "pattern": {
                    "regexp": "^$"
                },
                "background": {
                    "activeOnStart": true,
                    "beginsPattern": "yarn run.*",
                    "endsPattern": ".*Compiled successfully.*"
                }
            },
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}
```

名前が `npm: debug` のタスクを作成しています。

デバッグ中、 `npm run debug` は終了してほしくないので、 `"isBackground": true` にしています。

ただし、このままだとデバッグ準備がいつ完了したのか、VS Codeはわかりません。 `problemMatcher` を定義することで、わかるようにします。

#### problemMatcherの内容

私の環境の場合、 `webpack-dev-server` がデバッグ起動すると、開始時に `yarn run` という文字列が出力されるので、それをタスク開始の合図として `beginsPattern` に指定しています。これは、ご自身の環境によると思いますので、ご注意ください。
同様に、起動が完了すると、 `Compiled successfully` という文字列が出力されるので、それを `endsPattern` に指定しています。これも、ご自身の環境にあわせて適宜変更してください。

これらの設定は、以下を参考にしました。

- [Integrate with External Tools via Tasks](https://code.visualstudio.com/docs/editor/tasks)

- [Vue+Nuxt+TypeScript のプロジェクトを VSCode でデバッグ可能にする](https://qiita.com/amay077/items/cddd1bbd158ea4e79647)



## settings.jsonを編集する

さきほど作った `.vscode/settings.json` ファイルを編集します。

#### settings.json

```json
{
    "debug.javascript.usePreview": false,
    "debug.allowBreakpointsEverywhere": true,
    "terminal.integrated.shellArgs.linux": [
        "-l"
    ]
}
```

`terminal.integrated.shellArgs.linux` が追加されました。これは、OSの環境変数を、VS Code内のシェルへ反映する設定です。 `tasks.json` からnpmへのPATHを通すことが目的です。



## launch.jsonを編集する

さきほど作った `.vscode/launch.json` ファイルを編集します。

#### launch.json

```json
{
    "version": "0.2.0",
 	"configurations": [
        {
            "name": "Launch Chrome",
            "type": "pwa-chrome",
            "request": "launch",
            "preLaunchTask": "npm: debug",
            "url": "http://localhost:9223",
            "webRoot": "${workspaceFolder}",
            "sourceMapPathOverrides": {
                "webpack:///./*": "${webRoot}/react/*",
            }
        }
    ]
}
```

`"preLaunchTask": "npm: debug"` が追加されました。これにより、デバッグ起動時に、前処理として `webpack-dev-server` が自動で実行されるようになります。

以上で自動化できるようになりました！お疲れさまです！



# さいごに

本記事作成にあたり、以下の記事を参考にさせていただきました。ありがとうございました！

- [VSCodeでReactをデバッグする方法](https://qiita.com/keisukeengineer/items/cb64984597d2aa5a3952)
- [VSCodeでwebpack-dev-server上のReactをデバッグする](https://qiita.com/yusuke_impl/items/c92e2af7c16b3b76283d)
- [VSCodeでTypeScriptのブレークポイントが効かないときの対応](https://www.exceedsystem.net/2020/11/21/how-to-set-breakpoint-on-typescript-with-vscode/)
- [VisualStudioCode + TypeScript でブレークポイントが効かなかった問題（解決）](https://qiita.com/ttoonnaa/items/cb6a898e1f94a2692d14)
- [Visual Studio CodeでTypeScript開発のノウハウ (ブラウザ編)](https://qiita.com/takao_mofumofu/items/4f8d365846e2f770bd6e)
- [What is the pwa-node type launch configuration on VSCode?](https://stackoverflow.com/questions/63442436/what-is-the-pwa-node-type-launch-configuration-on-vscode)
- [VSCodeのDebugger for ChromeにおけるsourceMapPathOverrides設定メモ](https://qiita.com/beeeyan/items/9b0def365d64d11a4a1c)
- [Integrate with External Tools via Tasks](https://code.visualstudio.com/docs/editor/tasks)
- [Vue+Nuxt+TypeScript のプロジェクトを VSCode でデバッグ可能にする](https://qiita.com/amay077/items/cddd1bbd158ea4e79647)