Charles' Profile picture
Hi, I'm Charles Szilagyi, full-stack engineer, founder, mentor. I'm using software to make things better without making them worse in London, UK.

Debug anything: React in TypeScript with Parcel πŸ“¦

04 May 2020
3 min read

When it comes to front-end, my weapon of choice right now is the React, TypeScript and Parcel trinity. It's an easy, robust and productive setup, with minimal configuration. This guide will show you how to create a matching debugger experience in VS Code.

Get the code

You can skip ahead if you already have a React, TypeScript and Parcel project. Otherwise, let's check out the example code:

git clone git@github.com:thekarel/debug-anything.git
cd debug-anything/parcel
yarn # or npm i

1588237853 debuganything 06 01 code

Code structure

The application itself is elementary: you'll see a list of fake blog post titles, clicking on a title will fetch the body of the post and display it above the list.

The code in this folder is, as usual, kept as simple as possible so that we can focus our attention on the debugger. In a production app, we'd use a human-friendly folder structure. The entry point is index.html which pulls in index.tsx and runs the basic React app.

You should focus on the following files:

Post.ts # The Post interface type
Posts.tsx # The post-list React component
index.html # The entry-point
index.tsx # The React app
postRepository.ts # Data fetching module

Less than 100 lines altogether, so don't expect anything revolutionary πŸ˜‰

Parcel

You might be wondering where is the Webpack or Babel configuration file? Well, there's none! Since Parcel is a zero-configuration bundler, we can just tell it to compile the code, and it Just Works all the time. I find it easier to work with than other solutions like Create React App as it's so simple and fast.

In this example, we can bundle the whole React app, written in TypeScript, by simply pointing Parcel to index.html - and that's all the plumbing we need. One less thing to worry about. Deserves a star ⭐️ on GitHub πŸ‘

Note: this example code uses Parcel 2 alpha 3.

Dev server

Let's start the dev server with yarn start or npm start:

╰─$ yarn start
yarn run v1.22.4
$ parcel index.html
ℹ️ Server running at http://localhost:1234
✨ Built in 548ms

Make sure you can visit http://localhost:1234

The "app" fetches the list of posts on start, then grabs the selected post's body from the server on click.

Configure the debugger

What we'd like to achieve in terms of debugging, is to be able to set breakpoints in VS Code, launch a debug browser and step through the initial list fetch and subsequent remote requests.

To make this as easy and comfortable as possible, we'll take advantage of the launch.json configuration file. It's actually all prepared for you 😌

1588237880 debuganything 06 03 launchjson

Let's look at .vscode/launch.json and focus on the React+TS, Parcel section:

{
    "type": "chrome",
    "request": "launch",
    "name": "Debug React, TS, Parcel app in Chrome",
    "url": "http://localhost:1234/",
    "webRoot": "${workspaceFolder}/parcel",
    "pathMapping": {
        "__parcel_source_root": "${workspaceFolder}/parcel"
    },
        "skipFiles": [
        "${workspaceFolder}/parcel/node_modules/**/*.js",
        "<node_internals>/**/*.js"
    ]
},

The config is very similar to our Create React App example, by the way.

The type and request parameters tell VS Code to start debugging in a new Chrome window. It will use an empty profile by the way, without extensions or personal settings.

The name of the launcher will appear in the debug toolbar, plus the status bar of the IDE, after the 1st run:

1588237982 debuganything 06 04 name

The url needs to match the address where our dev version is served (http://localhost:1234/ by default).

webRoot: the filesystem path that matches the root of the dev server. It is usually the folder where the entry point is kept - in our case the folder where index.html is. Keep in mind that the example code repo houses multiple small projects. In a single-project repo, "webRoot": "${workspaceFolder}/src" is a good first guess.

pathMapping: this option is required in our case, as Parcel serves up a source-map that makes it look like the original files are under /__parcel_source_root. Without this setting VS Code would be unable to map breakpoint locations in the source to runtime code:

1588237889 debuganything 06 05 breakpoint bound

Check your pathMapping if you encounter "Breakpoint set but not yet bound" issues

You can find the correct path in the debug browser by the way. In Chrome, open the dev console and go to Sources:

1588237892 debuganything 06 06 find map name

Finally, we set skipFiles so that the debugger never steps into 3rd party or core Node.js modules. Skipping such files is useful if you want to focus on your codebase and are not interested in spending time looking at library codeβ€”a highly recommended tweak.

React + TypeScript debugger in action

Make sure the dev server is running, then launch the debug browser:

Let's add two breakpoints: one inside the fetchBody function, another into the useEffect hook:

1588237903 debuganything 06 08 breakp

Now we can restart the debugger (not the server!) and check the hook's behaviour when the component is mounted first:

Next, we can follow the code flow of fetchBody - note how we never see any core or 3rd party libraries (like Fetch or React internals):

Hopefully, you'll be able to implement a comfortable debug workflow in your React/TypeScript app based on this template ✌️

Have any tips or comments to share? Let me know!