A while ago there was an article on how developers use Node.js by Rising Stack. In a survey they asked Node.js developers for example what kind of database or message queue they use. Beside the question on how users deal with async programming one of the most interesting topics was debugging. Over 80% of the participants use
console.log in order to debug their application. This made me think. Often I find myself inserting
console.log statements in my code in order to see what’s happening – but why? The answer is easy: It’s inconvenient to use the debugger if you haven’t set up your environment correctly. In this article I’ll show you different approaches to debug your applications and their advantages.
Before we start with actually debugging our application, let’s see what our debugger should at least provide us:
- Breakpoints: Stop on a certain point in our application
- Environment: Show us the current environment at each breakpoint
- Watch Expressions: Let us define expressions that are evaluated on each break
- Console: A possibility to execute code within the current application environment
- Integration: The debugger should be integrated in our working environment
Node.js ships with a built-in debugging facility. If you start your application on the command line with
node debug index.js where
index.js is the starting point of your application then it is started in debug mode. This command has two effects: You start an interactive debugging shell and you open a TCP connection on port 5858 where you can connect a remote debugger with your application. The CLI debugger is the most uncomfortable solution directly after debugging with
console.log. But you have a set of commands that make it possible to navigate within your application at run time.
Even better debugging
--inspect flag landed in Node.js and with it a much better debugging support. In contrast to node-inspector you don’t have to install any additional module in order to get the
--inspect flag working. You just have to start your application with this flag.
As soon as you start your application, Node.js provides you with a URL which you have to copy to the address field of your Chrome browser. Your browser then connects to your Node.js instance and lets you debug and profile your application. This includes setting breakpoints and watch expressions or capturing memory snapshots of your application.
It’s surprisingly easy to get your debugging environment started in Visual Studio Code, which is by the way just another Node.js application. You just have to hit the debug button on the left side of the window and select the environment you want to debug (Node.js). Visual Studio Code then creates the launch configuration for you and saves it to the
.vscode/launch.json file in the root folder of your application. Depending on the starting point of your application you have to make an adjustment here. VSCode expects your application to start at
app.js. If you name the starting point differently, just go to
launch.json and change the value of the program key. After this is done, you can launch your debugger and have a look at your application.
For this example I created a simple web server. In order to debug this application, you have to set a breakpoint (by clicking on the left of the line number), launch the debugger and go to the server URL in your local browser. The application then automatically stops at your breakpoint and you can start stepping through your code.
As you see, there’s no more need for
console.log statements to debug your application code. Just start the debugger of your choice and have a comfortable interface to have a look at your code at run time.