I have an Angular project and currently debugging inside vs code via debugger for chrome. My launch.json uses "preLaunchTask": "serve" where serve is defined in tasks.json as "ng serve" so that I have "ng serve" executed first and sever is ready before browser is opened by debugger to hit http://localhost:4200.
Everything works fine. However, when I stop debugging, I still have "ng serve" task running as expected and I have to terminate that task manually every time.
I tried to use "postDebugTask" in launch.json but not much luck as vs code will complain about starting a new task (postDebug) until another running task (preLaunch) is not terminated. Could anyone please help?
As pointed out in this S.O. answer, the ability to run workbench commands from tasks was recently added to VSCode. It appears as though the best solution to this problem is to run the following task "postDebugTask": "end serve"
{
"label": "end serve",
"type": "process",
"command":[
"${command:workbench.action.tasks.terminate}"
],
},
This will prompt you to select the task you want to terminate from a drop down list. Unfortunately, I haven't been able to find a way to tell VSCode what task you want to terminate via an argument.
As pointed out in the linked answer, if you only have one task to choose from, you can automatically select that task with
{
"label": "end serve",
"type": "process",
"command":[
"${command:workbench.action.tasks.terminate}",
"${command:workbench.action.acceptSelectedQuickOpenItem}",
],
},
Thus eliminating the drop down menu.
After looking into this for a while, there doesn't seem to be any clean way to kill a task in VS Code that was kicked off as part of preBuildTask. It's a build task, and the debug task itself appears to be separate from that. Since the debug PID itself is targeted at Chrome, there's a weird separation between the two.
So, let's brute force it.
First, we need to get our initial ng serve running as a child process so another task won't complain about the first task hogging the terminal. This task worked for me:
{
"version": "2.0.0",
"tasks": [
{
"label": "serve",
"command": "ng serve",
"isBackground": true,
"type": "shell",
"presentation": {
"reveal": "always"
},
"problemMatcher": {
"fileLocation": "relative",
"background": {
}
}
}
]
}
Note the isBackground property. This will spawn any future tasks in their own shell. presentation is reveal: always so we can see the CLI output. We can get fancy and capture CLI problems with the debug process in problemMatcher, but let's forget it for now.
Now, let's make a kill task. Instead of working through VS Code to find the initial spawned task, let's do it through our OS. Now this is highly dependent on which OS and which shell you use (shells can be configured per task via the shell property).
We need to find the PID of the ng serve shell and send it off to the big computer in the sky. We can look for the PID hogging the localhost port being served against, which I'll assume is 4200 by default.
Example CMD command:
for /F "tokens=1,2,3,4,5" %A in ('"netstat -a -n -o | find 4200""') DO ('"Taskill /PID %E /F"')
Example bash/terminal command (simpler, as usual):
[sudo] lsof -ti:4200 | xargs kill
Then just make a kill task with the command and add it to postDebugTask:
{
"label": "kill",
"command": "lsof -ti:4200 | xargs kill",
"type": "shell",
}
If you run into access rights, you can probably fix it by running VS Code as admin or by providing a path to an .exe where you already have admin rights. Again, depends on your shell and OS.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With