Back in January, I wrote about a launch.json file to turn VS code into an end-to-end web debugging environment. One of the features people told me was missing was to start and stop a server with the debugging session. So here is how to do this.
We add two more lines to the existing launch.json
, defining a task to run before debugging starts and one after it ends. Let's call them start server
and stop server
respectively:
{
"version": "0.2.0",
"configurations": [
{
"type": "pwa-msedge",
"request": "launch",
"name": "webdebug",
"url": "http://localhost:8080",
"webRoot": "${workspaceFolder}",
"runtimeExecutable": "stable",
"runtimeArgs": ["--headless"],
"preLaunchTask": "start server",
"postDebugTask": "stop server"
}
]
}
We then need to create a tasks.json
file in the .vscode
folder that describes these tasks. Here is the final result:
{
"version": "2.0.0",
"tasks": [
{
"label": "start server",
"type": "shell",
"isBackground": true,
"command": "http-server",
"presentation": { "reveal": "silent" },
"problemMatcher": [{
"pattern": [{
"regexp": ".",
"file": 1,"line": 1,
"column": 1,"message": 1
}],
"background": {
"activeOnStart": true,
"beginsPattern": { "regexp": "." },
"endsPattern": { "regexp": "." }
},
}]
},
{
"label": "stop server",
"command": "echo ${input:terminate}",
"type": "shell"
},
],
"inputs": [{
"id": "terminate",
"type": "command",
"command": "workbench.action.tasks.terminate",
"args": "terminateAll"
}]
}
Tasks are meant to run, have an end and then tell the debugger that they are ready. Normally you would, for example, use them to do some conversion or pull some information. In this case, it is a bit trickier, as we start a server and that doesn't give us any feedback. The task never ends as the server starts and keeps running.
The start server
task is a shell
task, should run in the background and the command it executes is http-server
, which is the NPM module of the same name. The presentation property is set to silent, which means that when the server starts, it doesn't pop up the terminal in Visual Studio Code. When we use background tasks, we need to define a problemMatcher
that tells the debug process if the task has executed successfully or if there was any issue. This can get rather complex and you need to parse the output on the Console with Regular Expressions. In this case, we keep it very open and allow anything reported on the output Console to be a success (RegEx ".").
What this task does is open a new Terminal, enter "http-server" and hit enter for us. And once that's done, we have a local server at our disposal, making the current Workspace folder available as localhost:8080
, which is also what we defined in our launch.json
as the address to navigate to.
The stop server
task is a bit simpler. we just make it send a terminate
command to the terminal. We then use an inputs
directive to define the terminal
CLI command as something that calls workbench.action.tasks.terminate
with an argument of terminateAll
. This closes any Terminals opened by tasks earlier.
And that's all there is to spawn a new local server when you start debugging and close it when the debug session ends.
There is currently a bug in VS Code, that throws an error in your tasks when the Problems
pane is not empty when the task runs. In the case of using the Edge Developer tools for VS Code extension that means any issue reported there will result in this problem. I reported this to the team and they are working on a solution.
If you want to see this in action, you can fork the simple to-do demo and run it locally. Make sure to have http-server installed via NPM.