ちょっと話題の記事

【React も AWS CDK も】何も考えず VS Code に全任せして TypeScript コードをステップ実行デバッグする【できるよ!】

2020.12.28

環境構築

何もしてないのにできた」を実現するため、この記事ではインストール直後の Visual Studio Code と Node.js を使用しています。皆さんは今まで通りの環境で大丈夫です。

各ツール類のバージョンは執筆時点で最新のものを使用しています。

プロジェクト作成

任意のディレクトリを作成し、初期化して必要なモジュールをインストールします。そして VS Code で開きましょう。

mkdir ts
cd ts
npm init -y
npm install typescript ts-node -y
code .

ここまでいたって普通。特別なことは何もしていません。

コーディング

それではステップ実行するためにプログラムを書きましょう。サンプルらしく Fizz Buzz を採用します。

1 から順番に数字が与えられる。
3 の倍数の時、Fizz を出力する。
5 の倍数の時、Buzz を出力する。
15 の倍数の時、FizzBuzz を出力する。
それ以外の時、与えられた数字を出力する。

書きました!

fizzbuzz.ts

for (let i = 1; i <= 30; i++) {
    console.log(fizzbuzz(i))
}

function fizzbuzz(num: number): string | number {
    if (num % 3 === 0) return 'Fizz'
    else if (num % 5 === 0) return 'Buzz'
    else if (num % 15 === 0) return 'FizzBuzz'
    return num
}

プログラマーたるもの FizzBuzz くらいスラスラと書けますよね。さぁ実行してみましょう!

./node_modules/.bin/ts-node fizzbuzz.ts
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
Fizz
16
17
Fizz
19
Buzz
Fizz
22
23
Fizz
Buzz
26
Fizz
28
29
Fizz

"FizzBuzz" が出力されてねぇ……。

ステップ実行デバッグ

茶番にお付き合いいただきありがとうございます。本題のステップ実行をやっていきます。

ブレークポイントを設定する

行番号の左側にマウスポインタを持っていくと薄い赤丸が表示され、クリックすると明るい赤丸が浮かび上がってきます。これが ブレークポイント です。

それでは fizzbuzz 関数の先頭行である6行目にブレークポイントを設定しましょう。

JavaScript Debug Terminal を起動する

VS Code の左端のバー(アクティビティバー)から「実行」を開き、以下の画像で示した JavaScript Debug Terminal ボタンをクリックします。

そうすると以下のようにターミナルが開けば準備完了です。

デバッグ実行する

それではこのターミナルで、先ほどと同じ実行コマンドを入力してみましょう。

./node_modules/.bin/ts-node fizzbuzz.ts

……!

ブレークポイントで止まっていますね。左側のサイドバーに num: 1 と表示されていることから1回目のループで止まっていることも確認できます。

このコードでは、15の倍数の時に FizzBuzz が出力されなかったので、 num: 15 の処理を見ていきましょう。num が15になるまで続行ボタンを連打でもいいのですが、もっとスマートにいきます。

ブレイクポイントを右クリックして「ブレークポイント の編集…」をクリックし、以下のように num === 15 と条件を入力し Enter キーを押します。

(Visual Studio Code でも条件付きブレークポイントを設定できることをこの記事の執筆で知りました🤣)

そして下記画像の左端にある三角ボタンを押して続行しましょう。

15 で止まりましたね! クリック連打回避で腱鞘炎も回避できました。

それでは15の時の処理を見ていきます。下記画像の左から2番目のボタンを押して ステップオーバー しましょう。

1回押すと、カーソルが return の位置まで移動しました。

もう1回ステップオーバーすると return の後ろ側にカーソルが移動します。

そしてもう1回ステップオーバーすると i: 15 となっている for 文の中に移動しました。

さらにもう1回ステップオーバーすると……。

Fizz が出力されました。15 は 3 で割り切れるので Fizz が出力される現場を目撃することができました。

原因がわかりましたので続行を押してデバッグを終了しましょう。

修正する

15は3で割り切れるので、それより先に「15で割り切れるか」の判定を持っていけばよさそうです。

修正しました。

fizzbuzz.ts

for (let i = 1; i <= 30; i++) {
    console.log(fizzbuzz(i))
}

function fizzbuzz(num: number): string | number {
    if (num % 15 === 0) return 'FizzBuzz'
    else if (num % 3 === 0) return 'Fizz'
    else if (num % 5 === 0) return 'Buzz'
    return num
}

ブレークポイントは不要なので赤丸を押して削除しましょう。位置的に評価されないので。

そして実行します。ドキドキ。

./node_modules/.bin/ts-node fizzbuzz.ts
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz
Fizz
22
23
Fizz
Buzz
26
Fizz
28
29
FizzBuzz

ドヤァ

[おまけ] React もステップ実行!

VS Code 拡張機能「Debugger for Chrome」をインストールすればさらに世界は広がります。

サンプルとして React のチュートリアルでおなじみの Tic Tac Toe を用います。

VS Code は .vscode/launch.json にデバッグ構成を記述できます。今回は以下のように設定しています。

.vscode/launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "chrome",
            "request": "launch",
            "name": "Launch Chrome against localhost",
            "url": "http://localhost:3000",
            "webRoot": "${workspaceFolder}"
        }
    ]
}

そして JavaScript Debug Terminal ではなく、通常のターミナルを使います。

npm run start

以下のように launch.json と ローカルで開いているポートが一致していれば準備完了です。

launch.json を記述したのでサイドバーの表示が変わっています。上部の実行ボタンを押してください。

任意の .tsx ファイルにブレークポイントを設定し、先ほど開かれた Chrome 上で操作すると止まります!

この React のデバッグは公式ドキュメントにも記載されている由緒正しきデバッグ設定を用いています。その分「何もしてないのにできた」とは言えませんが、知っていて損はないでしょう。

[おまけ] AWS CDK もステップ実行!

AWS CDK で作成したプロジェクトのテストをステップ実行します。サンプルアプリをそのまま使います。テストも用意されているのがいいですね。

cdk init sample-app --language=typescript

任意の個所にブレークポイントを設定し、 JavaScript Debug Terminal にてテストを実行します。

npm run test

ね? 簡単でしょ?

まとめ

VS Code 標準機能の JavaScript Debug Terminal に全乗っかりして、JavaScript/TypeScript コードをステップ実行を簡単に行うことができました。

React のような SPA でも拡張機能をインストールすることでブラウザの操作をトリガーにしてステップ実行することができました。

記事内でもちょろんっと触れましたが VS Code では launch.json にデバッグ構成を記述できます。拡張機能をインストールすれば Python や C# や Go や PHP といった様々な言語でも同じようにステップ実行をすることができます。詳しくは公式ドキュメントをどうぞ。

皆さんがデバッグを駆使して課題解決までの時間が短くなりますように。