Debugging JavaScript with the Node Debugger

It’s a trap! You’ve spent a good amount of time making changes, nothing works. Perusing through the code shows no signs of errors. You go over the logic once, twice or thrice, and run it a few times more. Even unit tests can’t save you now, they too are failing. This feels like staring at an empty void without knowing what to do. You feel alone, in the dark, and starting to get pretty angry.

A natural response is to throw code quality out and litter everything that gets in the way. This means sprinkling a few print lines here and there and hope something works. This is shooting in pitch black and you know there isn’t much hope.

You think the darkness is your ally

Does this sound all too familiar? If you’ve ever written more than a few lines of JavaScript, you may have experienced this darkness. There will come a time when a scary program will leave you in an empty void. At some point, it is not smart to face peril alone with primitive tools and techniques. If you are not careful, you’ll find yourself wasting hours to identify trivial bugs.

The better approach is to equip yourself with good tooling. A good debugger shortens the feedback loop and makes you more effective. The good news is Node has a very good one out of the box. The Node debugger is versatile and works with any chunk of JavaScript.

Below are strategies that have saved me from wasting valuable time in JavaScript.

The Node CLI Debugger

The Node debugger command line is a useful tool. If you are ever in a bind and can’t access a fancy editor, for any reason, this will help. The tooling uses a TCP-based protocol to debug with the debugging client. The command line client accesses the process via a port and gives you a debugging session.

You run the tool with node debug myScript.js, notice the debug flag between the two. Here are a few commands I find you must memorize:

  • sb('myScript.js', 1) set a breakpoint on first line of your script
  • c continue the paused process until you hit a breakpoint
  • repl open the debugger’s Read-Eval-Print-Loop (REPL) for evaluation

Don’t Mind the Entry Point

When you set the initial breakpoint, one tip is that it’s not necessary to set it at the entry point. Say myScript.js, for example, requires myOtherScript.js. The tool lets you set a breakpoint in myOtherScript.js although it is not the entry point.

For example:

// myScript.js
var otherScript = require('./myOtherScript');

var aDuck = otherScript();

Say that other script does:

// myOtherScript.js
module.exports = function myOtherScript() {
  var dabbler = {
    name: 'Dabbler',
    attributes: [
      { inSeaWater: false },
      { canDive: false }
    ]
  };

  return dabbler;
};

If myScript.js is the entry point, don’t worry. You can still set a breakpoint like this, for example, sb('myOtherScript.js', 10). The debugger does not care that the other module is not the entry point. Ignore the warning, if you see one, as long as the breakpoint is set right. The Node debugger may complain that the module hasn’t loaded yet.

Time for a Demo of Ducks

Time for a demo! Say you want to debug the following program:

function getAllDucks() {
  var ducks = { types: [
    {
      name: 'Dabbler',
      attributes: [
        { inSeaWater: false },
        { canDive: false }
      ]
    },
    {
      name: 'Eider',
      attributes: [
        { inSeaWater: true },
        { canDive: true }
      ]
    } ] };

  return ducks;
}

getAllDucks();

Using the CLI tooling, this is how you’d do a debugging session:

> node debug debuggingFun.js
> sb(18)
> c
> repl

Continue reading %Debugging JavaScript with the Node Debugger%


Source: Sitepoint