C# .NET Stalker Debugger All-in-One C# .NET (5+ and Core) and JavaScript/TypeScript DebuggerUse this debugger, instead of
Primary Features🚫 No need to manually stop, re-attach or restart debuggers or run multiple tasks 🚫 There are three primary features of .NET Stalker Debugger.
TL;DR
👨🏼💻 Use Cases for DevelopersAll use cases of .NET Stalker Debugger have all primary features (Build, Debug and Watch-Reload/Rebuild-Reattach) in a single debug session that is native to Visual Studio Code and its tooling. 🔙 Backend Developer
🌕 Full-Stack & 📄 Front-End Developers (Similar Launch Configurations)
🕵 The .NET Stalker Debugger Life-Cycle
Phases and ToolingLogical order of phases within the three primary features. Depending on the launch configuration, some phases may not be used.
RequirementsSupported OS's (at least tested on)Works on modern versions of linux (Ubuntu), macOS and Windows, where the requirements can be installed. Requirements
Requirements for Client-Side Debugging
Launch Configurations
When adding/modifying a launch configuration in Properties
Type
|
Property | Type | Description | Required | Default | Defined Values |
---|---|---|---|---|---|
action |
string |
Action to take when the child process is initially attached to. | openExternally |
nothing , openExternally , debugWithChrome , debugWithFirefox , debugWithEdge |
|
interval |
number |
Interval in milliseconds to attempt to re-attach to the process after a full hot load build (as well as initially at startup). | 500 |
||
urlPath |
string |
URL path to open when attaching to the process. | "" |
||
taskProperties |
{[key]:any} |
Properties for internal the Visual Studio Code attach task. | { logging: { moduleLoad: false } } |
||
browserTaskProperties |
{[key]:any} |
Properties for internal the Visual Studio Code browser debug task. | {} |
Type buildOptions
Properties
Options relating to building.
Property | Type | Description | Required | Default | Defined Values |
---|---|---|---|---|---|
preBuildTasks |
see below | Tasks to run before running .NET Watch (which builds and runs the project). Tasks are run in order. By default, tasks are not treated as background tasks and are waited for before continuing. Use isBackground and waitFor change behavior. Default is an empty array. |
[] |
Type preBuildTask
Properties
Property | Type | Description | Required | Default | Defined Values |
---|---|---|---|---|---|
name |
string |
Name of the task to run. | Yes | ||
commandLine |
string |
Command line to run. | Yes | ||
isBackground |
boolean |
Indicate whether the task is a background task or not. | false |
||
waitFor |
boolean |
Indicate whether to wait for the task to complete before continuing. | true |
||
failOnNonZeroExitCode |
boolean |
Indicate whether to fail the build if the task has a non-zero exit code. | true |
||
problemMatcher |
string |
Problem matcher to use for the task. |
Type processOptions
Properties
Options for child process started by .NET Watch.
Property | Type | Description | Required | Default | Defined Values |
---|---|---|---|---|---|
args |
array |
Arguments passed to the child process. | [] |
||
launchSettingsProfile |
string |
launch settings profile (in Properties/launchSettings.json ) to start the child process with. If used, the url property is ignored. |
Type watchOptions
Properties
Options for .NET Watch.
Property | Type | Description | Required | Default | Defined Values |
---|---|---|---|---|---|
args |
array |
Arguments passed to .NET Watch. | [] |
||
disableOptimizations |
boolean |
Disable MSBuild optimizations. | false |
||
doNotLaunchBrowser |
boolean |
Do not launch the browser if the processOptions.launchSettingsProfile property is used and is configured to do so. Ignored if processOptions.action is not nothing . |
false |
||
doNotRefreshBrowser |
boolean |
"Do not refresh the browser when changes are detected. | false |
||
dotnet |
string |
Path to the dotnet executable. | dotnet |
||
interval |
number |
Interval in milliseconds to check if child process has restarted, after a hot load build, to re-attach to it. | 1000 |
||
noEmojis |
boolean |
Disable emojis in the console output. | false |
||
usePollingFileWatcher |
boolean |
Use polling file watcher. This is required for some file systems, such as network shares, Docker mounted volumes, and other virtual file systems. | false |
||
verbose |
boolean |
Enable verbose logging for .NET Watch. | false |
If the browser is not refreshing on detected changes, see the usePollingFileWatcher
property and dotnet-watch browser refresh.
See dotnet-watch configuration for more information on some of these watch options.
Examples
Minimum launch configuration
{
"name": ".NET Stalker",
"type": "stalker",
"request": "launch",
"project": "${workspaceFolder}/src/MyWebApp/MyWebApp.csproj",
"process": "${workspaceFolder}/src/MyWebApp/bin/Debug/net9.0/MyWebApp",
"cwd": "${workspaceFolder}/src/MyWebApp",
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
Minimum launch configuration with specific URL and use of variables
{
"name": ".NET Stalker",
"type": "stalker",
"request": "launch",
"vars": {
"framework": "net9.0",
"projectDir": "${workspaceFolder}/src/${var:projectName}",
"projectName": "MyWebApp"
},
"project": "${var:projectDir}/${var:projectName}.csproj",
"process": "${var:projectDir}/bin/Debug/${var:framework}/${var:projectName}",
"cwd": "${var:projectDir}",
"url": "http://localhost:8080",
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
Full launch configuration with ESLint, Webpack (watch mode) and Google Chrome (or Mozilla Firefox or Microsoft Edge) client-side debugging
{
"name": ".NET Stalker (Full)",
"type": "stalker",
"request": "launch",
"vars": {
"framework": "net9.0",
"projectDir": "${workspaceFolder}/src/${var:projectName}",
"projectName": "<PROJECTNAME>"
},
"project": "${var:projectDir}/${var:projectName}.csproj",
"process": "${var:projectDir}/bin/Debug/${var:framework}/${var:projectName}",
"cwd": "${var:projectDir}",
"env": {
"ASPNETCORE_ENVIRONMENT": "Development",
"NODE_ENV": "development"
},
"url": "http://localhost:5001",
"webRoot": "${var:projectDir}/wwwroot",
"buildOptions": {
"preBuildTasks": [
{
"name": "ESLint",
"commandLine": "npx eslint --color ./scripts"
},
{
"name": "Webpack",
"commandLine": "npx webpack --watch --node-env ${env:NODE_ENV} --mode ${env:NODE_ENV} --devtool source-map --color",
"isBackground": true,
"waitFor": false,
"problemMatcher": "$stalker-webpack-watch"
}
]
},
"attachOptions": {
"action": "debugWithChrome",
"urlPath": "/swagger"
}
}
Note: Set attachOptions.action
to debugWithFirefox
to debug with Mozilla Firefox or debugWithEdge
to debug with Microsoft Edge.
Client-Side JavaScript/TypeScript Debugging
For .NET Stalker Debugger to support client-side JavaScript/TypeScript debugging (i.e. hit breakpoints within Visual Studio Code), some configuration is needed.
While there are many ways to configure a project for client-side debugging, this section provides an example setup using both ESLint and Webpack. You're free to use any other configuration that suits your needs.
Requirements:
- Supported browser (Google Chrome, Mozilla Firefox or Microsoft Edge)
- Node.js
- Node package dependencies
- TypeScript, ESLint and Webpack configuration files
- .NET Stalker Debugger launch configuration modifications
Note that client-side debugging is not required for .NET Stalker Debugger to work. It is only needed if you want to debug client-side code within Visual Studio Code. Also, use of TypeScript (and Webpack) is not required for client-side debugging, but it is used in this example.
Supported Browsers
- Google Chrome: Download here.
- Mozilla Firefox: Use Firefox Developer Edition.
- Microsoft Edge: If not pre-installed, download here.
Note: Safari does not support remote debugging thus it is not supported by this extension.
Node.js
See Node.js for installation.
Node Package Dependencies
In the project directory (i.e. ${workspaceFolder}/src/(projectName)
), run:
npm i --save-dev @types/bootstrap @types/glob @types/jquery @types/node @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint glob path ts-loader ts-node typescript webpack webpack-cli
npm i --save @popperjs/core bootstrap jquery
TypeScript, ESLint and Webpack Configuration Files
TypeScript File
An noteworthy values here is compilerOptions.outDir
which is referenced by the Webpack configuration.
${workspaceFolder}/src/(projectName)/tsconfig.json
{
"compilerOptions": {
"noEmitOnError": true,
"noImplicitAny": true,
"sourceMap": true,
"outDir": "wwwroot/js",
"esModuleInterop": true,
"target": "ESNext",
"module": "commonjs",
"allowJs": true,
"checkJs": true
},
"exclude": ["./node_modules/", "./wwwroot/", "./webpack.config.ts"],
"include": ["./scripts/**/*.ts"],
"compileOnSave": true
}
ESLint Files
${workspaceFolder}/src/(projectName)/eslint.config.mjs
import typescriptEslint from "@typescript-eslint/eslint-plugin";
import tsParser from "@typescript-eslint/parser";
export default [
{
files: ["**/*.ts"],
ignores: ["./node_modules/**"],
},
{
plugins: {
"@typescript-eslint": typescriptEslint,
},
languageOptions: {
parser: tsParser,
ecmaVersion: 2022,
sourceType: "module",
},
rules: {
"@typescript-eslint/naming-convention": [
"warn",
{
selector: "import",
format: ["camelCase", "PascalCase"],
},
],
curly: ["warn", "multi-line"],
eqeqeq: "warn",
"no-throw-literal": "warn",
semi: "warn",
"no-unused-vars": "warn",
"no-unreachable": "warn",
"no-unused-expressions": "warn",
},
},
];
${workspaceFolder}/src/(projectName)/.eslintignore
**/node_modules/*
**/webpack.config.ts
**/wwwroot/js/*
Webpack File
Two noteworthy values here are entry
and output.path
which are used to transpile TypeScript files in directory ./script
to JavaScript to the wwwroot/js
directory.
${workspaceFolder}/src/(projectName)/webpack.config.ts
import { glob } from "glob";
import { resolve } from "path";
import { Configuration } from "webpack";
const config: Configuration = {
entry: glob.sync("./scripts/**/*.ts").reduce((entries, path) => {
const entry = path.replace(/(.*\/)?scripts\//, "").replace(".ts", "");
path = "./" + path;
entries[entry] = path;
return entries;
}, {} as { [key: string]: string }),
output: {
path: resolve(__dirname, "wwwroot/js"),
filename: "[name].js",
devtoolModuleFilenameTemplate: "[absolute-resource-path]",
},
infrastructureLogging: { level: "log" },
devtool: "source-map",
target: "web",
resolve: {
extensions: [".ts", ".js"],
},
module: {
rules: [
{
test: /\.ts$/,
use: "ts-loader",
},
],
},
};
export default config;
Launch Configuration Modifications
Before starting the .NET Stalker Debugger, pre-build tasks are needed to:
- (Optionally) Run ESLint
- (Required) Use Webpack to transpile TypeScript files to JavaScript to the
wwwroot/js
directory
Important: Pre-build tasks are executed in the order they are defined. Ensure ESLint is run before Webpack.
Pre-Build Task: ESLint
Editing an existing .NET Stalker Debugger launch configuration, append to root level:
"buildOptions": {
"preBuildTasks": [
{
"name": "ESLint",
"commandLine": "npx eslint --color ./scripts",
}
]
}
Pre-Build Task: Webpack
Editing an existing .NET Stalker Debugger launch configuration, append to root level:
"env": {
"NODE_ENV": "development"
}
As well as:
"buildOptions": {
"preBuildTasks": [
{
"name": "Webpack",
"commandLine": "npx webpack --watch --node-env ${env:NODE_ENV} --mode ${env:NODE_ENV} --devtool source-map --color",
"isBackground": true,
"waitFor": false,
"problemMatcher": "$stalker-webpack-watch"
}
]
}
To disable the Webpack watch mode (i.e. no "hot transpiles" on file changes), remove --watch
from the commandLine
property.
Extension Settings
There are no global/user extension settings. All settings are configured on a project-level in a launch.json
file.