Web App Development

Time-travel debugging Node programs with Visual Studio Code

Microsoft are working on a time-travel debugger for JavaScript that allows you to step backward as well as forward. It’s currently in preview and won’t always work, but it’s really cool to play around with.

Downloading VS Code Insider build and Node-ChakraCore

To try it out you first need to install the Visual Studio Code Insider build.

Rather than using the normal V8 based version of Node you need to use Node-ChakraCore, which uses Microsoft’s JavaScript engine.

The readme suggests using Node Version Switcher to install Node-ChakraCore. But, if you would rather not risk having yet another Node version manager mess up your system, I would recommend directly downloading the prebuilt binaries.

I had some issues with the latest release, but those are fixed in the nightly build. Just select the most recent build based on the date.

Once there’s a newer version than 7.0.0-pre10 on the releases page you can also download it there.

After downloading Node-ChakraCore, unzip the file, find the node executable in the bin folder, and copy the path to it.

Code Setup

In VS Code, open the folder containing your JavaScript code.

Create a test.js file with the following content:

setTimeout(function(){
    var a = 5;
    a += 6;
    debugger;
}, 200)

Record replay data

Then, in the terminal, run test.js with the downloaded Node-ChakraCore build. To be able to time travel later you need to install recording using the -TTRecord flag.

Run this in the directory that contains test.js:

/Users/mattDownloads/node-v7.0.0-nightly2016...-darwin-x64/bin/node -TTRecord:log test.js 

(The exact path will depend on where you downloaded the node executable to.)

This will create a log directory containing the time travel data recorded by Node-ChakraCore.

Configure the VS Code project

In the VS Code sidebar select the debugger. Click the “Start Debugging” button to start configuring the project.

In the dropdown just select Node.js for now.

We need to make a few manual changes to the launch.json file that was just created.

First, change the program property to test.js.

Then add a runtimeExecutable property that contains the location of the downloaded Node-ChakraCore binary.

Finally, add a runtimeArgs property with the value ["-TTDebug:log", "-TTBreakFirst"].

        "runtimeExecutable": "/Users/.../node-nightly.../bin/node",
        "runtimeArgs": ["-TTDebug:log", "-TTBreakFirst"]

Your launch.json file will look something like this:

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "launch",
            "name": "Launch Program",
            "program": "${workspaceRoot}/test.js",
            "cwd": "${workspaceRoot}",
            "runtimeExecutable": "/Users/.../node-nightly.../bin/node",
            "runtimeArgs": ["-TTDebug:log", "-TTBreakFirst"]
        },
        {
            "type": "node",
            "request": "attach",
            "name": "Attach to Process",
            "port": 5858
        }
    ]
}

Time-travel debugging

Now click the “Start Debugging” button again and VS Code will pause at the debugger statement in test.js.

Right now the value of a is 11. Use the “Step Back” button in the stepping controls and see how the value in the Variables pane is updated to the previous value.

Trying your own code

You can change the content of test.js as you like, but you’ll have to update the recording in the terminal before debugging in VS Code.

telemetryLog

When debugging in VS Code you won’t be able to see output generated by console.log calls.

However, you can instead use the telemetryLog function.

setTimeout(function(){
    var a = 5;
    a += 6;
    debugger;
    telemetryLog(a.toString(), true);
}, 200)

Note that unlike console.log, the first parameter to telemetryLog has to be a string. The second parameter (printFlag) indicates whether the log should appear in the console during the replay.

More info

For more info, take a look at the time-travel debugging readme in the Node-ChakraCore repo.


Follow me on Twitter