At work I’ve been building features for a complex CMS dashboard that’s transitioning from AngularJS to Angular 4. It’s a behemoth of an application that sports a fairly robust build process and a healthy mix of tooling. To facilitate the build we use Gulp which handles copying, linting, compiling, bundling and more.

In one particular build step, we lint LESS and compile it to CSS. When the stylesheets are compiled, we kick off a watcher which monitors LESS files and recompiles them anytime a change has been made. This is great when it works, but the process had begun to show signs of disrepair. The watcher was no longer recompiling upon changes, which meant that a developer would have to manually call the compileLess task from the terminal every time they wanted to see a style change appear in the browser. This added minutes to the development workflow and cut into the developer’s feedback loop. As weeks turn into months, the context switching and idle time adds up and becomes costly for the developer, their team, and employer.

With the topic front-of-mind, and my frustration simmering, I decided to find a fix. Enter the VS Code debugger….

Setup

To begin with Visual Studio Code’s built in debugger, select the bug symbol in the left side bar and click on the settings cog to access debugger configurations. Alternatively, you can get here in the Debug -> Open Configurations top menu. Debugger configurations are stored in JSON format at the root level of your project in the VS Code workspace directory. More specifically, you can find it at <app-root>/.vscode/launch.json .

Setup your launch.json to begin debugging with VS Code

Once here, you may find some preset configurations, but we’ll want to add our own. Select the Add Configuration… button in the bottom right corner of the launch.json window and IntelliSense will provide options to add a launch configuration snippet. For a comprehensive list of launch configuration attributes and common snippets, head here.

Gulp

In the example above, I am demonstrating setup to debug a specific gulp task titled watchLess . Upon clicking the Add Configuration… button, we are presented with options to add some boilerplate. I select the Node.js: Gulp task option and customize it for the watchLess task.

Once I’ve saved the configuration file, you will notice that the new debug option we added can now be selected in the drop-down at the top of the debugger pane. Note that the name property of the configuration object determines how the task will appear in the debugger drop down.

Toggle breakpoints by clicking on the editor margin. Right-click to add conditional breakpoints

From here we can set a breakpoint. Previous investigation had shown that the bug was likely coming from the task’s handleIncludeCompile function, but I needed help confirming that hunch. In the above gif you can see as I place a breakpoint within the function in its respective file.

After the breakpoint is set, we can start debugging by pressing F5 or by clicking the green start button. The gulp task is now running and sure enough, the debugger stops at our breakpoint after a change is made to a random *.less file. Once we hit the breakpoint, we can resume code execution F5 , step over F10 , into F11 , or out Shift + F11 of a function.

When the debugger stops at the breakpoint in the screenshot below, we’re able to see a great deal more information than was afforded to us with simple logging statements. In the left hand pane we can inspect the code’s variables and their data at a given point of execution. We’re also able to hover over previously executed code to see variable values.

As it turns out, the src paths that were passed in the config object had outdated glob patterns and no longer worked with our updated build structure, hence the reason the watch task wasn’t properly recompiling.

The data provided in the left hand panel of the debugger helped to identify an outdated glob pattern in the src path

Don’t worry if the example doesn’t quite make sense, just know that the debugger enabled us to pause the gulp task and view data at a given point in time, thereby helping us identify and squash the bug.

Browser

As someone who’s accustomed to debugging in Chome’s devtools, I was doubtful that a VS Code extension would make a difference. That was until I read this terrific post from Kenneth Auchenberg on the popular Debugger for Chrome extension. The extension allows the use of the VS Code debugger in lieu of the browser’s dev tools, allowing a developer to eliminate a step from a standard debugging workflow.

To get started, download the Debugger for Chrome extension. You will find beginning steps for some popular frameworks/libraries below.

Speed up your debugging skills

React

Create a React app using create-react-app Open your project’s launch.json and add the following configuration

3. Start your React app by running npm start or yarn run start in the terminal

4. Begin debugging in VS Code by setting a breakpoint and pressing F5

Angular

Create Angular app using Angular CLI Make sure Chrome is version 59 or greater (see issue) Open your project’s launch.json and add the following configuration

4. Start your Angular app by running ng serve in the terminal

5. Begin debugging in VS Code by setting a breakpoint and pressing F5

Vue

Create Vue app using vue-cli Open your project’s launch.json and add the following configuration

4. Start your Vue app by running npm run dev in the terminal

5. Begin debugging in VS Code by setting a breakpoint and pressing F5

Attaching to Chrome

To attach to Chrome as opposed to launching a new window, use the "request": "attach" config option. Before attaching you will need to launch Chrome with remote debugging enabled.

Windows

Right click the Chrome shortcut, and select properties

In the “target” field, append --remote-debugging-port=9222

Or in a command prompt, execute <path to chrome>/chrome.exe --remote-debugging-port=9222

macOS

In a terminal, execute /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222

Linux

In a terminal, launch google-chrome --remote-debugging-port=9222

Example “Attach” config

A Quick Note on Source Maps

The Debugger for Chrome extension uses source maps to let you debug your original sources, but you may find yourself in a situation where source maps aren’t generated properly and overrides are needed. In the launch config you can set overrides by using the sourceMapPathOverrides option. This is useful when the source map isn’t accurate or can’t be fixed in the build process.

More information on source maps in Debugger for Chrome can be found here.