TypeScriptのデバッグ

TypeScriptのデバッグ方法は多くの方が紹介していますが、実際に自分でやってみるといくつか躓きポイントがあったので備忘録として残します。TypeScriptをJavaScriptに変換(トランスパイル)するコマンドをインストールするのにnpmが必要になりますので、実際に試してみたい方はこちらのサイト様等を参考にしてNode.jsをインストールしておいてください。実行環境はWindows版のVSCodeを使用しています。最初からすべて設定しないで簡単な設定から徐々に設定を増やしていこうと思います。

今回の記事を作成するにあたり、以下の講座で勉強させていただきました。講師の方の知識がとても豊富で、今回ご紹介するデバッグ関連の他にもTypeScriptの様々な文法や機能、JavaScriptライブラリとの連携方法や、ReactやNode.js(Express)などのフレームワークとの連携方法など様々な知識が勉強できます。また、講座の中で紹介されているデモアプリの作成を通じて実践的な記述方法なども学習できます。

Udemy

超TypeScript 完全ガイド 2025

TypeScriptのコンパイラをインストールします

任意の名称のフォルダ(TypeScript等)を作成してVSCodeで開きます。(サンプルではc:MAMP\htdocsフォルダ内に作成していますが、どこに作成しても問題ありません。) VSCodeで「Ctrl + @」と入力してターミナル画面を表示します。表示されたターミナル画面に「npm install -g typescript」と入力して、TypeScriptのコンパイラ(tsc)をインストールします。

正常にインストールできたか確認するために、ターミナル画面に「tsc -v」と入力します。以下の様なエラーが発生した場合はVSCodeの設定を修正します。

VSCodeで「Ctrl + Shift + p」と入力して、コマンドパレットを表示します。検索欄に「open user」と入力して、表示された「基本設定:ユーザー設定を開く (JSON)」項目を選択します。

表示された「settings.json」ファイルの任意の位置に以下の設定項目を追加して保存します。

    "terminal.integrated.env.windows": {
        "PSExecutionPolicyPreference": "RemoteSigned"
    },

ターミナル画面のゴミ箱アイコンをクリックして閉じます。

再度ターミナル画面を表示して「tsc -v」と入力します。何かバージョンが表示されれば正常に動作しています。

TypeScriptのコンパイラ設定を修正します

ターミナル画面に「tsc --init」と入力してtscの設定ファイル(tsconfig.json)を作成します。作成された設定ファイルを開いて、「inlineSourceMap」項目を検索してコメントを外して保存します。

サンプルファイルを作成してコンパイルします

実行テスト用に以下のhtmlファイル(index.html)とTypeScriptファイル(index.ts)を作成します。(スクリプトでDOM操作をしたいので、スクリプトタグに「defer」属性を追加して最後に実行する様にしています。)

<!DOCTYPE html>
<html lang="ja">
<head>
    <title>TypeScript</title>
    <script src="index.js" defer></script>
</head>
<body>
    <h1></h1>
</body>
</html>
const h1 = document.querySelector('h1') as HTMLHeadingElement;
h1.textContent = 'OK';

ターミナル画面に「tsc」と入力して、JavaScriptファイル(index.js)が作成されれば正常に動作しています。「tsc -w」と入力してウォッチモードと呼ばれるモードでコマンドを起動したままにしておけば、TypeScriptファイルが修正されたら自動でJavaScriptファイルが更新されます。

デバッガーを起動するために作業フォルダ内に「.vscode\launch.json」ファイルを作成して、以下の様な設定を書き込みます。

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "chrome",
            "request": "launch",
            "name": "localhost に対して Chrome を起動する",
            "url": "http://localhost:8080",
            "webRoot": "${workspaceFolder}"
        }
    ]
}

ターミナル画面に「php -S localhost:8080」等と入力して簡易的なWEBサーバーを起動してから、F5キーを押すか実行ボタンでデバッガーを起動するとTypeScriptファイルに設定したブレークポイントで停止します。

以上でデバッグできる様になりましたが、何個もターミナル画面を立ち上げたくないのでもう少しデバッグ環境を整えます。

デバッグ環境を修正します

VSCodeの左側にある「拡張機能」ボタンを押します。表示された画面の検索欄に「live server」と入力して表示されたプラグインをインストールします。

こちらのサイト様を参考にして、デバッガーが起動したらLive Serverも起動する様に設定して行きます。先ほど追加した「.vscode\launch.json」ファイルを開いて以下の様に修正します。

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch Chrome",
            "request": "launch",
            "type": "chrome",
            "url": "http://localhost:5500/",
            "webRoot": "${workspaceFolder}",
            "preLaunchTask": "StartServer",
            "postDebugTask": "StopServer"
        },
    ],
}

.vscodeフォルダ内に「tasks.json」というファイルを作成して以下の内容を書き込みます。

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "StartServer",
            "type": "process",
            "command": "${input:startServer}",
        },
        {
            "label": "StopServer",
            "type": "process",
            "command": "${input:stopServer}"
        }
    ],
    "inputs": [
        {
            "id": "startServer",
            "type": "command",
            "command": "extension.liveServer.goOnline"
        },
        {
            "id": "stopServer",
            "type": "command",
            "command": "extension.liveServer.goOffline"
        }
    ]
}

このままではデバッグ時にVSCodeとLive Serverがそれぞれブラウザーを起動してしまうので、Live Serverが起動したときにブラウザーを起動しない様に設定します。VSCodeで「Ctrl + Shift + p」と入力して、コマンドパレットを表示します。検索欄に「open user」と入力して、表示された「基本設定:ユーザー設定を開く (JSON)」項目を選択します。

表示された「settings.json」ファイルの任意の位置に以下の設定項目を追加して保存します。(HTMLファイル名の右クリックメニュー(Open with Live Server)でブラウザーが起動しなくなりますので、不都合がある場合はこの設定を削除してください。)

    "liveServer.settings.NoBrowser": true,

VSCodeでデバッグを開始するとLive Serverが自動的に起動します。

ターミナル画面で「tsc -w」と入力してTypeScriptコンパイラーをウォッチモードで起動しておくと、TypeScriptファイルが変更されるたびに自動的にコンパイルされてさらにLive Serverによって自動的に再読み込みされます。

ソースファイルと配布ファイルを別フォルダーに分割します

TypeScriptファイルが増えた場合に管理が大変になるので、ソース(TypeScript)ファイルと配布ファイルをそれぞれ別のフォルダで管理できる様に設定を修正します。

ルートフォルダ内に「src」というフォルダを作成して、「index.ts」ファイルを移動します。生成されたindex.jsファイルは削除します。「index.html」ファイルを以下の様に修正します。

<!DOCTYPE html>
<html lang="ja">
<head>
    <title>TypeScript</title>
    <script src="dist/index.js" defer></script>
</head>
<body>
    <h1></h1>
</body>
</html>

「tsconfig.json」設定ファイルを開いて、「rootDir」項目のコメントを外して以下の様に変更します。

    "rootDir": "./src",                                  /* Specify the root folder within your source files. */

同様に「outDir」項目のコメントを外して以下の様に変更します。

    "outDir": "./dist",                                  /* Specify an output folder for all emitted files. */

VSCodeのターミナル画面に「tsc」と入力して、左側のエクスプローラー画面に「dist」フォルダと「index.js」ファイルが作成されていれば正常に動作しています。

複数ファイルのコンパイルを確認するために、srcフォルダ内に「second.ts」というファイルを作成して以下の内容を書き込みます。

export function Message() : void {
    alert('test');
}

index.tsファイルを以下の様に修正します。「import」文を使用して別(second.ts)ファイルのMessageという関数を呼び出せる様にしています。

import { Message } from "./second.js";

const h1 = document.querySelector('h1') as HTMLHeadingElement;
h1.textContent = 'OK';
Message();

TypeScriptのデフォルトのコンパイル設定では、これらのファイルをJavaScriptのモジュールファイルに変換してくれないので、「tsconfig.json」を開いて以下の様にmodule設定を「ES6」に変更します。

    "module": "commonjs",                                /* Specify what module code is generated. */
    ↓
    "module": "ES6",                                     /* Specify what module code is generated. */

ブラウザ側も「import」文を含んだスクリプトファイルはモジュールとして認識してくれない様なので、scriptタグ文に「type="module"」という宣言を追加します。

<!DOCTYPE html>
<html lang="ja">
<head>
    <title>TypeScript</title>
    <script type="module" src="dist/index.js" defer></script>
</head>
<body>
    <h1></h1>
</body>
</html>

すべてのファイルを保存してコンパイルします。実行して以下の様な画面になれば正常に動作しています。

配布ファイルを単一ファイルに統合します (Webpack)

これまでの設定でモジュール分割して開発できる様になりましたが、ソースファイルを分割すると同時に配布ファイル数も増加します。配布ファイルの増加はブラウザの読み込み時間に影響しますので、「モジュールバンドラー」と呼ばれるパッケージを導入して配布ファイルを単一のファイルに統合します。モジュールバンドラーは色々な種類がある様ですが、基本的な動作を理解するために「Webpack」というパッケージを使用します。

VSCodeのターミナル画面に以下のコマンドを入力して、「package.json」ファイルを作成します。

npm init -y

次に以下の様に入力してWebpackパッケージをインストールします。「--save-dev」や「-D」は開発用オプションなどと呼ばれている様です。これらのオプションでインストールされたパッケージは、「npm install --production」と入力するとパッケージの復元処理から除外される様です。

npm install --save-dev webpack webpack-cli
または
npm install -D webpack webpack-cli

次にWebpackの設定ファイル「webpack.config.js」を作成して、以下の設定を書き込んで保存します。設定内容は「dist」フォルダ内にある「index.js」ファイルを起点として、統合したファイルを「bundle.js」という名称で同じフォルダ(dist)内に保存するという意味になっています。最後の行(devtool)を追加しておくとデバッグ情報(ソースマップ)が同じファイル内に出力されるので、ソースコード(TypeScript)に直接ブレークポイントを設定してデバッグが可能になります。

const path = require('path');
module.exports = {
    entry: './dist/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    devtool: 'inline-source-map'
}

「package.json」ファイルを開いて、以下の文字列がある場合はその行を削除します。

  "type": "commonjs",

同じ設定ファイルの"scripts"設定に「"build": "webpack"」という文字列を追加します。前の行("test")の末尾にカンマ(,)を追加します。以降はターミナル画面に「npm run build」と入力するとWebpackコマンドが実行されます。

  "scripts": {
    "test": "echo "Error: no test specified" && exit 1",
    "build": "webpack"
  },

index.htmlファイルを以下の様に修正します。統合されたファイル(bundle.js)は1行に圧縮されていて「import」文が無いので「type="module"」宣言は必要なくなりました。

<!DOCTYPE html>
<html lang="ja">
<head>
    <title>TypeScript</title>
    <script src="dist/bundle.js" defer></script>
</head>
<body>
    <h1></h1>
</body>
</html>

デバッガーを起動して動作を確認します。スクリプトファイル(bundle.js)は1行に圧縮されていますが、ソースコード(TypeScript)レベルでデバッグ可能です。

ソースコードから直接統合ファイルを作成します (ts-loader)

Webpackを使用すると複数の配布ファイルを統合できますが、事前にtscコマンドでJavaScriptファイルを生成しておく必要があります。直接TypeScriptファイルから統合ファイル(bundle.js等)を生成できた方が便利です。

VSCodeのターミナル画面に以下の様に入力します。

npm install -D ts-loader typescript

Webpackの設定ファイル「webpack.config.js」を開いて以下の様に修正します。

const path = require('path');
const { Extension } = require('typescript');
module.exports = {
    entry: './src/index.ts',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    devtool: 'inline-source-map',
    module: {
        rules: [{
            test: /.ts$/,
            use: 'ts-loader',
            exclude: /mode_modules/
        }]
    },
    resolve: {
        extensions: ['.ts', '.js']
    }
}

index.tsファイルを開いて、1行目のimport文から以下の様に拡張子を削除します。

import { Message } from "./second.js";
↓
import { Message } from "./second";

あとは「npm run build」と入力してビルドすれば、ソースファイルから統合されたファイルが直接作成されます。

ブレークポイントで止まらない場合は

統合されたファイルが圧縮されすぎていて、対応するコードが無くなってしまったかマップ情報が不足しているためと思われます。Webpackの設定ファイル「webpack.config.js」を開いて以下の様に「mode」項目を追加して、開発モードで統合ファイルを作成すると改善する場合がある様です。

const path = require('path');
const { Extension } = require('typescript');
module.exports = {
    mode: 'development',
    entry: './src/index.ts',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    devtool: 'inline-source-map',
    module: {
        rules: [{
            test: /.ts$/,
            use: 'ts-loader',
            exclude: /mode_modules/
        }]
    },
    resolve: {
        extensions: ['.ts', '.js']
    }
}

開発モードでコンパイルするとファイルサイズがかなり大きくなる様なので、デバッグが終了したら「mode: 'production'」と変更するか、設定項目自体を削除します。

ビルドコマンドを自動で実行するには

tscコマンドのウォッチモードの様に、ファイルが変更されたら自動でコンパイルされると便利かもしれません。

本来ならWebpackの開発用サーバー等を使用したほうがいいと思われますが、とりあえずファイル保存時にコマンドを実行するだけなら以下の様なプラグインがある様です。拡張機能の検索欄で「run on save」と入力すると表示されます。

プラグインのインストール後に、「Ctrl + Shift + p」で表示されるコマンドパレットから設定ファイル(setting.json)を開いて、以下の設定を追加するとTypeScriptのファイルが保存されるたびにnpmのコンパイルコマンドが実行されます。デバッガーを起動しておけば自動的にファイルが再読み込みされます。

    "emeraldwalk.runonsave": {
        "commands": [
            {
                "match": "\.ts$",
                "cmd": "npm run build"
            },
        ]
    }
JavaScriptのパッケージを使用するには

npmでインストールされたパッケージをTypeScriptで使用するには、「tsconfig.json」設定ファイル内にある「moduleResolution」設定のコメントを外して、値を「bundler」に変更します。

おまけで実際に動作するか確認するために、「Swapy」というパッケージを使用してみます。このパッケージを使用すると画面上のアイテムをマウスのドラッグ操作で入れ替えることが出来ます。

VSCodeのターミナル画面に以下の様に入力してSwapyをインストールします。

npm install swapy

「index.html」と「index.ts」と「second.ts」ファイルを以下の様に修正します。

<!DOCTYPE html>
<html lang="ja">
<head>
    <title>TypeScript</title>
    <link rel="stylesheet" href="app.css">
    <script src="dist/bundle.js" defer></script>
</head>
<body>
    <h1></h1>
    <section id="container">
        <div data-swapy-slot="1">
            <div data-swapy-item="a" style="background-color: #cbe0f4">A</div>
        </div>
        <div data-swapy-slot="2">
            <div data-swapy-item="b" style="background-color: #9bc4e0">B</div>
        </div>
        <div data-swapy-slot="3">
            <div data-swapy-item="c" style="background-color: #e5e1eb">C</div>
        </div>
        <div data-swapy-slot="4">
            <div data-swapy-item="d" style="background-color: #e3d7e6">D</div>
        </div>
        <div data-swapy-slot="5">
            <div data-swapy-item="e" style="background-color: #c7c9e0">E</div>
        </div>
    </section>
</body>
</html>
import { addMessage } from "./second";
import { createSwapy } from 'swapy';

const h1 = document.querySelector('h1') as HTMLHeadingElement;
h1.textContent = 'OK';
addMessage(h1);

const container = document.querySelector('#container') as HTMLElement;
const swapy = createSwapy(container, {
    animation: 'dynamic'
})
swapy.enable(true);
export function Message(): void {
    alert('test');
}

export function addMessage(h: HTMLHeadingElement): void {
    h.textContent += ', second OK.';
}

また、スタイルを修正するために「app.css」というファイルを作成して以下の内容を書き込みます。

h1 {
    text-align: center;
}

#container {
    width: 90%;
    margin: 0 auto;
    display: flex;
    flex-direction: row;
    justify-content: space-evenly;
    flex-wrap: wrap;
}

div {
    height: 200px;
    flex-basis: 200px;
    flex-grow: 1;
    border-radius: 5px;
    display: grid;
    place-items: center;
}

div:hover {
    cursor: pointer;
}

#container>div {
    display: flex;
    border: 1px solid #a4c1d3;
    margin: 0.5px;
}

TypeScriptファイルをコンパイルして実行してみると、特に問題なく動作している様です。

余談ですがJavaScriptで開発を行う場合も、Webpack等のバンドラーを使用したほうがいいと思われます。パッケージのソースファイルを開発用のフォルダにコピーしても動作させることはできそうですが、高機能なパッケージ程どの様な依存関係を持っているか分かりませんので、パッケージマネージャに管理してもらった方が効率がいいと思われます。

以上です。よろしかったらお試しください。