How to debug TypeScript in WebStorm?
Tags: typescript, webstorm, debug
Published: 2023-02-19 08:10:55

<!-- wp:paragraph -->
<p>In this article, I want to show you how WebStorm can debug TypeScript code. As you know, TypeScript code should be compiled into JavaScript before running in a browser or NodeJS. After compilation code will not be the same. If you want to put a breakpoint and check variable values, you have to tell the debugger where it should stop. How to do that? </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>I will set up a project from scratch and show you how to make the WebStorm debugger work. </p>
<!-- /wp:paragraph -->

<!-- wp:more -->
<!--more-->
<!-- /wp:more -->

<!-- wp:paragraph -->
<p><strong>Long Story Short</strong>: you need to set <em>sourceMap</em> parameter in <em>tsconfig.json</em> to true. It will tell <em>tsc</em> to build source maps and that will help WebStorm to know where to stop if you put a breakpoint.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>Setup the TypeScript project</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p><em><em>First of all, you should have installed NodeJS and WebStorm to make all scripts on commands works. Also, all terminal commands might not work in Windows systems.</em></em></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><em>And one more important thing. Of course, you can debug with console.log and don't use any external debugger. However, I should say sometimes the program's complexity makes console.log debugging pretty hard. Better to have some tools in the pocket that will allow you to use more power. </em></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Let's set up an empty project first. We can create a directory and initialize npm there by following commands. </p>
<!-- /wp:paragraph -->

<!-- wp:enlighter/codeblock -->
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># create directory
mkdir typescript-debug-webstorm

# go inside directory
cd typescript-debug-webstorm

# initialize empty npm project
npm init -y</pre>
<!-- /wp:enlighter/codeblock -->

<!-- wp:paragraph -->
<p>To make TypeScript work we need to install it and initialize it. Let's do that.</p>
<!-- /wp:paragraph -->

<!-- wp:enlighter/codeblock -->
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># installing TypeScript
npm i --save-dev typescript

# initialize default configuration
npx tsc --init</pre>
<!-- /wp:enlighter/codeblock -->

<!-- wp:paragraph -->
<p>Now I would like to set up a basic directories structure. My preference is to use <em>src</em> directory for TypeScript files, and <em>dist</em> directory for compiled code. </p>
<!-- /wp:paragraph -->

<!-- wp:enlighter/codeblock -->
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># create both directories 
mkdir src 
mkdir dist</pre>
<!-- /wp:enlighter/codeblock -->

<!-- wp:paragraph -->
<p>Now time to edit TypeScript configuration and make it work as excepted with my directories. Open the directory in WebStorm, and then open the<em> tsconfig.json</em> file. Afterward we need to edit it a bit to make it work with my preferred directory structure. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>TypeScript compiler will scan <em>src</em> directory by default. As for <em>dist </em>directory<em>,</em> we need to edit the parameter outDir. Find it in the file, remove the comment, and change it to <em>./dist</em>. </p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center","id":2822,"width":658,"height":388,"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image aligncenter size-large is-resized"><img src="https://jakeroid.com/wp-content/uploads/2023/02/image-1024x604.png" alt="outDir parameter inside tsconfig" class="wp-image-2822" width="658" height="388"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Now time to test our setup before we move to debug. Let's create a simple <em>index.ts</em> file inside the <em>src</em> directory. </p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center","id":2824,"width":807,"height":266,"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image aligncenter size-large is-resized"><img src="https://jakeroid.com/wp-content/uploads/2023/02/image-1-1024x338.png" alt="simple typescript project in webstorm" class="wp-image-2824" width="807" height="266"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>And here is the code.</p>
<!-- /wp:paragraph -->

<!-- wp:enlighter/codeblock -->
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">function main() {
    console.log('Hello World! We will setup TypeScript debugging in WebStorm!');
}

main();</pre>
<!-- /wp:enlighter/codeblock -->

<!-- wp:paragraph -->
<p>Let's compile it and run it by executing the following commands. </p>
<!-- /wp:paragraph -->

<!-- wp:enlighter/codeblock -->
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># compile source (you could also just run tsc)
npx tsc 

# run 
node dist/index.js</pre>
<!-- /wp:enlighter/codeblock -->

<!-- wp:image {"id":2825,"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image size-large"><img src="https://jakeroid.com/wp-content/uploads/2023/02/image-2-1024x236.png" alt="" class="wp-image-2825"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Nice! As a result it looks like everything is working. But noted let's set up one more thing before we will move to debugging. I am talking about npm commands. Open the <em>package.json</em> file and add a few commands inside the scripts section. Here is my result <em>package.json</em> file. </p>
<!-- /wp:paragraph -->

<!-- wp:enlighter/codeblock -->
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">{
  "name": "typescript-debug-webstorm",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" &amp;&amp; exit 1",
    "build": "npx tsc",
    "prestart": "npm run build",
    "start": "node dist/index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "typescript": "^4.9.5"
  }
}</pre>
<!-- /wp:enlighter/codeblock -->

<!-- wp:paragraph -->
<p>As you can see, I added the commands <em>build</em> and <em>start</em>. Also, I added a pre-command, which will run before each start execution <em>start</em>. Now we can run our program by following the command, and the source code will be compiled automatically. That is possible because before each start we run the build command which compiles our sources via TypeScript compiler. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Let's change our program code a bit and rerun the program. </p>
<!-- /wp:paragraph -->

<!-- wp:enlighter/codeblock -->
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">function main() {

    console.log('Hello World! We will setup TypeScript debugging in WebStorm!');
    for (let i = 0; i &lt; 10; i++) {
        console.log(`Debugging is fun! ${i}`);
    }
}

main();</pre>
<!-- /wp:enlighter/codeblock -->

<!-- wp:enlighter/codeblock -->
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># run our program by following command
npm run start </pre>
<!-- /wp:enlighter/codeblock -->

<!-- wp:image {"align":"center","id":2826,"width":774,"height":577,"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image aligncenter size-large is-resized"><img src="https://jakeroid.com/wp-content/uploads/2023/02/image-3-1024x765.png" alt="debugging with typescript and webstorm" class="wp-image-2826" width="774" height="577"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>It looks like everything is working. Okay, now let's move to setting up the debugger. </p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>Debugging TypeScript in WebStorm</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>First, let's add run configuration to our WebStorm settings. </p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><!-- wp:list-item -->
<li>Open <em>Edit Configurations</em> popup.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Then press on "+" to add new.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>In the new popup, select <em>npm</em>.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>After select the command <em>start</em> from the scripts menu.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Press <em>OK</em>.</li>
<!-- /wp:list-item --></ol>
<!-- /wp:list -->

<!-- wp:image {"align":"center","id":2829,"width":540,"height":284,"sizeSlug":"full","linkDestination":"none"} -->
<figure class="wp-block-image aligncenter size-full is-resized"><img src="https://jakeroid.com/wp-content/uploads/2023/02/image-5.png" alt="edit run configuration in webstorm" class="wp-image-2829" width="540" height="284"/><figcaption class="wp-element-caption">1. Open <em>Edit</em> <em>Configurations</em> popup.</figcaption></figure>
<!-- /wp:image -->

<!-- wp:image {"align":"center","id":2830,"width":746,"height":373,"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image aligncenter size-large is-resized"><img src="https://jakeroid.com/wp-content/uploads/2023/02/image-4-1024x513.png" alt="add new run configuration in webstorm" class="wp-image-2830" width="746" height="373"/><figcaption class="wp-element-caption">2. Then press on "+" to add new. </figcaption></figure>
<!-- /wp:image -->

<!-- wp:image {"align":"center","id":2831,"width":465,"height":895,"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image aligncenter size-large is-resized"><img src="https://jakeroid.com/wp-content/uploads/2023/02/image-6-532x1024.png" alt="npm run configuration webstorm" class="wp-image-2831" width="465" height="895"/><figcaption class="wp-element-caption">3. In the new popup, select "<em>npm</em>". </figcaption></figure>
<!-- /wp:image -->

<!-- wp:image {"align":"center","id":2832,"width":827,"height":610,"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image aligncenter size-large is-resized"><img src="https://jakeroid.com/wp-content/uploads/2023/02/image-7-1024x757.png" alt="selection script in npm run configuration webstorm" class="wp-image-2832" width="827" height="610"/><figcaption class="wp-element-caption">4. After select the command <em>start</em> from the sripts menu.</figcaption></figure>
<!-- /wp:image -->

<!-- wp:image {"align":"center","id":2835,"sizeSlug":"full","linkDestination":"none"} -->
<figure class="wp-block-image aligncenter size-full"><img src="https://jakeroid.com/wp-content/uploads/2023/02/image-8.png" alt="buttons in run configuration window webstorm" class="wp-image-2835"/><figcaption class="wp-element-caption">5. Press <em>OK</em></figcaption></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>After all, we are done with the configurations. Let's try to debug. Put breakpoint somewhere, for example, on the second console.log call. To do that, click on the line number on the left. </p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center","id":2837,"width":788,"height":202,"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image aligncenter size-large is-resized"><img src="https://jakeroid.com/wp-content/uploads/2023/02/image-10-1024x264.png" alt="typescript debug example" class="wp-image-2837" width="788" height="202"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Then press debug button on the top. Additionally don't miss one important thing: the <em>start</em> script should be selected like a current run configuration. </p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center","id":2838,"width":559,"height":177,"sizeSlug":"full","linkDestination":"none"} -->
<figure class="wp-block-image aligncenter size-full is-resized"><img src="https://jakeroid.com/wp-content/uploads/2023/02/image-9.png" alt="start debugging webstorm" class="wp-image-2838" width="559" height="177"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Nice, but... The program finished successfully, besides nothing happened with our breakpoint.</p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center","id":2839,"width":780,"height":596,"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image aligncenter size-large is-resized"><img src="https://jakeroid.com/wp-content/uploads/2023/02/image-11-1024x783.png" alt="debug example webstorm typescript" class="wp-image-2839" width="780" height="596"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Why did it happen? As I mentioned before, WebStorm doesn't know where to stop, because NodeJS executes compiled JavaScriopt code. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>How to fix it? We need to edit the <em>tsconfig.json</em> file and set <em>sourceMap parameter to true. That will tell TypeScript compiler to make a </em>source map between TypeScript and JavaScript code. Because of that WebStorm will know where is corresponding code. </p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center","id":2841,"width":711,"height":208,"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image aligncenter size-large is-resized"><img src="https://jakeroid.com/wp-content/uploads/2023/02/image-12-1024x299.png" alt="sourceMap parameter typescript config " class="wp-image-2841" width="711" height="208"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Let's try again to debug.</p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center","id":2842,"width":719,"height":209,"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image aligncenter size-large is-resized"><img src="https://jakeroid.com/wp-content/uploads/2023/02/image-13-1024x298.png" alt="debugger stop on breakpoint webstorm" class="wp-image-2842" width="719" height="209"/></figure>
<!-- /wp:image -->

<!-- wp:image {"align":"center","id":2843,"width":719,"height":258,"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image aligncenter size-large is-resized"><img src="https://jakeroid.com/wp-content/uploads/2023/02/image-14-1024x367.png" alt="debugger information window webstorm" class="wp-image-2843" width="719" height="258"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Finnaly it's working! After that you could use the <em>Resume Program</em> button and iterate via each loop statement inside the code. Awesome, isn't it? </p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center","id":2844,"width":480,"height":192,"sizeSlug":"full","linkDestination":"none"} -->
<figure class="wp-block-image aligncenter size-full is-resized"><img src="https://jakeroid.com/wp-content/uploads/2023/02/image-15.png" alt="resume program debugger in webstorm" class="wp-image-2844" width="480" height="192"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>In sum it isn't too hard to setup debugger for TypeScript in WebStorm. I hope you will be able to use the full power of the WebStorm debugger. If you have any questions feel free to ask them in the comments section below. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If you would like to check source files welcome to my GitHub: <a href="https://github.com/Jakeroid/blog-article-typescript-debug-webstorm" target="_blank" rel="noreferrer noopener">https://github.com/Jakeroid/blog-article-typescript-debug-webstorm</a>. </p>
<!-- /wp:paragraph -->