Yesterday I finally took the time to work on one of those tasks that had previously never quite bubbled up to the top of my priority list. Since I’ve been working on Dasher 360 I’ve put up with using the developer tools built into Chrome for debugging. While these are pretty good – especially with source-map support, allowing us to debug the source TypeScript code – which is the main reason I haven’t taken the time to do otherwise, they do have their limitations: just for instance, you very often start to edit code in the debugger before realising you’re not modifying the source itself. This regularly drives me crazy.
So it was that I took the time to work out how to use a couple of VS Code’s debugging capabilities. Both my co-developer – Simon Breslav – and I have ended up gravitating towards VS Code as our primary IDE. He’s using it on Windows while I use it on a Mac, which is in itself pretty cool – as well as being a good test of whether what we’re doing (and creating) is cross-platform. He’s out on vacation, this week, so it’ll be interesting to see whether the stuff I’ve done works over there without modification.
The first of VS Code’s debugging capabilities of interest to our project – and one that is integrated directly into the tool – is the ability to debug Node.js (i.e. server-side JavaScript). For now there’s not a significant amount of code on our server-side, although this will change, over time. My main reason for wanting this piece to work is for the ability to fire off a build – and launch the server, once it’s complete – without having to switch to a command prompt or terminal window.
The second – which needs to be installed via an extension – is the ability to integrate with Chrome debugging. This was ultimately the bigger priority for where we are today.
Both of these capabilities are enabled via the same mechanism: you need to add a launch.json file to your project’s .vscode folder. To integrate your build process, you’ll probably need to have a tasks.json defining that, too.
Here’s our current launch.json:
{
"version": "0.3.0",
"configurations": [
{
"name": "Launch server",
"type": "node",
"request": "launch",
"program": "${workspaceRoot}/src/server/index.js",
"stopOnEntry": false,
"args": [],
"cwd": "${workspaceRoot}",
"preLaunchTask": "build",
"runtimeExecutable": null,
"runtimeArgs": [
"--nolazy"
],
"env": {
"NODE_ENV": "development"
},
"console": "internalConsole",
"sourceMaps": false
},
{
"name": "Attach to server",
"type": "node",
"request": "attach",
"port": 5000,
"address": "localhost",
"restart": false,
"sourceMaps": false,
"localRoot": "${workspaceRoot}",
"remoteRoot": null
},
{
"name": "Launch localhost (sourcemaps)",
"type": "chrome",
"request": "launch",
"url": "http://localhost:5000",
"webRoot": "${workspaceRoot}/build/public",
"sourceMapPathOverrides": {
"/source/*": "${workspaceRoot}/*"
}
},
{
"name": "Launch Dasher 360 staging",
"type": "chrome",
"request": "launch",
"sourceMaps": false,
"url": "http://dasher-staging.not-the-real-url.com"
},
{
"name": "Launch Dasher 360 production",
"type": "chrome",
"request": "launch",
"sourceMaps": false,
"url": "http://dasher360.com"
}
]
}
It defines a couple of options for the Node server, although I admit that I’ve really only used the “launch” option, for now. “Attach” does seem to work, but my goal is to keep things in one place wherever possible.
On the front-end debugging side we have the ability to launch the localhost – with the ability to debug our TypeScript via source-maps, yay! – as well as the staging and production instances.
Here’s the tasks.json file that the “Launch server” configuration depends on for the build (for which we use gulp).
{
// See http://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "0.1.0",
"command": "gulp",
"isShellCommand": true,
"args": ["--no-color"],
"showOutput": "always",
"tasks": [
{
"taskName": "build",
"args": [],
"isBuildCommand": true,
"isWatching": false,
"problemMatcher": [
"$tsc"
]
}
]
}
I’d like to add other tasks to this file, but it currently only seems to support having a single one (unless you jump through some hoops that quickly mean you have an OS-specific solution, I expect).
Now when I debug I first launch the server, which also fires off a build…
Then I go and launch Chrome to open it…
At which point I have active debug sessions for both the server- and client-side code.
There’s almost certainly some further streamlining we can do with this process, but I’m pretty happy with how it’s working, for now. And the ability to debug directly from VS Code – and integrate code changes right into the project – is going to be fantastic.