NodeJS Debug & VSCode Debugger
A,Debugging
1.Debug
The debugger
- Debugger configuration management;
- Debugger start, stop, step operation;
- Source code, functions, conditions, breakpoints, and log points;
- Stack tracing, multithreading and multiprocess support;
- In the view and
hover
Browse complex data structures in the - Variable values are displayed in
hover
And source code; watch
Expression management- Debug console for automated interactive evaluation.
2. Start debugging
1. Create onetestvscodedebug
Directory in which to createindex.js
file
const a = '1';
const b = '2';
debugger;
for(let i = 0; i < 10; i++) {
console.log(i);
}
const arr = [1.2.3.4.5];
const isTrue = arr.some(item= > {
console.log(item);
return item > 4;
});
console.log(isTrue);
Copy the code
2. Click the debug button
You need to createlaunch.json
file
3. Click the “Create launch.json” button and selectNodeJS
You will notice that there is an extra one in the folder.vscode
There’s a folder in itlaunch.json
file
4. Click Debug again
Start debugging
5. Debug the toolbar
● Continue/Pause F5 ● Jump over F10 ● Step into F11 ● Go out registering F11 ● Restart registering F5 ● Stop registering F5
6. Red dot debugging
You don’t have to add it to the codedebugger
Add red dots on the side of the code to debug.
7. Log
Right-click on the red dot in each row and select Add Log PointFor example: This log point records in the loopi
Value:{i}
As you execute, you can see that logs are printed.
3,Launch.json
attribute
1. Static configuration
{
// Use IntelliSense to learn about related attributes.
// Hover to view descriptions of existing properties.
/ / for more information, please visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0"."configurations": []}Copy the code
2. configurations
configuration
interface common {
// Environment type, such as node
type: string
/ / the debug mode
request: 'launch' | 'attach'
// Debugger name The name displayed in debugger management
name: string
// Follow the protocol
protocol: 'auto' | 'inspector' | 'legacy'
// debug port
port: number
// Debug the TCP/IP address of the port
address: string
// Enable source mapping by setting this to true
sourceMaps: boolean
// An array of glob patterns used to locate generated JavaScript files
outFiles: array
// Restart the session on termination
restart: boolean
autoAttachChildProcesses: boolean
// When restarting the session, abort after this number of milliseconds
timeout: number
// Interrupt immediately when the program starts
stopOnEntry: boolean
// VS Code's root directory
localRoot: string
// Root directory of the node
remoteRoot: string
// Try to automatically skip code that is not mapped to the source file
smartStep: boolean
// Automatically skip these glob files
skipFiles: array
// Whether to enable diagnostic output
trace: boolean
presentation: {
// Whether to hide, true means to hide invisible default false
hidden: boolean,
// The smaller the sort number, the more first
order: number,
// the group name is the same as the group name
group: string
}
}
interface launch {
// The absolute path to the Node.js program to debug
program: string
// Parameters passed to program debugging
args: array
// Start the program in this directory for debugging
cwd: '${workspaceFolder}'
// The absolute path to the runtime executable to use. The default is the node
runtimeExecutable: 'node' | 'npm' | string
// Optional arguments passed to the Runtime executable
runtimeArgs: string
// Select a specific version of Node.js
runtimeVersion: string
// This property expects environment variables as a list of key/value pairs of string type
env: {}
// The optional path to the file containing the environment variable definition
envFile: '${workspaceFolder}/.env'
// Start the program console
console: 'internalConsole' | 'integratedTerminal' | 'externalTerminal'
outputCapture: string
}
interface attach {
// When using the processId attribute, the debug port is automatically determined based on node.js version (and protocol used) and cannot be explicitly configured. So do not specify the port attribute.
processId: string
}
Copy the code
3. Platform specific properties
Json supports different property values for different operating systems. Args uploads values on Windows, stopOnEntry uploads values on MacOS
{
"version": "0.2.0"."configurations": [{"type": "node"."request": "launch"."name": "Launch Program"."program": "${workspaceFolder}/node_modules/gulp/bin/gulpfile.js"."args": ["myFolder/path/app.js"]."windows": {
"args": ["myFolder\\path\\app.js"]},"stopOnEntry": true."osx": {
"stopOnEntry": false}}}]Copy the code
Windows
–windows
Linux
–linux
MacOS
–osx
4. Launch vs Attach
Launch refers to attaching debug sessions to the next node debugger that is launched directly (i.e. -inspect-brk =port). Attach means to attach debug sessions to the port of the specified running node program in Debug mode. If the node program is not in Debug mode, provide processId.
5. Source Maps
Source Maps is enabled by default. If the compiled file is not in the same directory, you need to set outFiles attribute to tell debug where the source adpater file is.
6. Variable substitution
Paths and other values commonly used by VSCode can be used as variables.
{
"type": "node"."request": "launch"."name": "Launch Program"."program": "${workspaceFolder}/app.js"."cwd": "${workspaceFolder}"."args": ["${env:USERNAME}"]}Copy the code
4, variables,
1. List of variables
${workspaceFolder}
– inVS Code
The path to the folder opened in${workspaceFolderBasename}
– inVS Code
The name of the folder opened in, without a slash (/);${file}
– Current open file;${fileWorkspaceFolder}
– Workspace folder of the currently open file;${relativeFile}
– relative to theworkspaceFolder
The currently open file;${relativeFileDirname}
– The directory name of the currently open file;${fileBasename}
– Of the currently open filebasename
;${fileBasenameNoExtension}
– Of the currently open filebasename
, no file extension;${fileDirname}
– Of the currently open filedirname
;${fileExtname}
– Extension of the current open file;${cwd}
– The current working directory of the task running program at startup;${lineNumber}
– The currently selected line number of the selected file;${selectedText}
– The currently selected text in the selected file;${execPath}
–VS Code
The running path of the executable file;${env:Name}
-Environment variables;${config:Name}
– Configure variables;${command:commandID}
–command
Variables;${defaultBuildTask}
– Name of the default build task;${pathSeparator}
– Character used to separate components in file paths;${input:variableID}
–input
Input variables.
Example 2.
Suppose you have the following requirements:
- Located in the
/home/your-username/your-project/folder/file.ext
Files opened in the editor; - The directory
/home/your-username/your-project
Opens as the root workspace.
Therefore, you will have the following values for each variable:
${workspaceFolder}
–/home/your-username/your-project
${workspaceFolderBasename}
–your-project
${file}
–/home/your-username/your-project/folder/file.ext
${fileWorkspaceFolder}
–/home/your-username/your-project
${relativeFile}
–folder/file.ext
${relativeFileDirname}
–folder
${fileBasename}
–file.ext
${fileBasenameNoExtension}
–file
${fileDirname}
–/home/your-username/your-project/folder
${fileExtname}
–.ext
${lineNumber}
– The line number of the cursor${selectedText}
– Selected text in the code editor${execPath}
–Code.exe
The location of the${pathSeparator}
– inmacOS
或linux
for/
In theWindows
upper\
3. Variables within the scope of each Workspace folder
You can access the peer root folder of your workspace by appending the name of the root folder to a variable (separated by a colon). If there is no root folder name, the scope of the variable is the same as the folder in which it is used. For example, in Client in a multi-root workspace with folders Server and, ${workspaceFolder:Client} refers to the path to the Client root.
4. Environment variables
You can also reference environment variables through the ${env:Name} syntax (for example, ${env:USERNAME}).
{
"type": "node"."request": "launch"."name": "Launch Program"."program": "${workspaceFolder}/app.js"."cwd": "${workspaceFolder}"."args": ["${env:USERNAME}"]}Copy the code
5. Config
variable
${config:Name}
${config:editor.fontSize}
6. Command
variable
${command:commandID}
{
"configurations": [{"type": "node"."request": "attach"."name": "Attach by Process ID"."processId": "${command:extension.pickNodeProcess}"}}]Copy the code
7. Input
variable
${input:variableID}
{
"version": "2.0.0"."tasks": [{"label": "task name"."command": "${input:variableID}"
// ...}]."inputs": [{"id": "variableID"."type": "type of input variable"
// type specific configuration attributes}}]Copy the code
Currently VS Code supports three types of input variables:
promptString
: Displays an input box to get a string from the user.pickString
: Displays a quick selection drop-down menu that allows the user to select from multiple options.command
: Runs any command.
PromptString
:description
: displays in quick input to provide context for input.default
: The default value will be used if the user enters no other content.password
: set totrue
Enter with a password prompt that does not display the typed value.
PickString
:description
: appears in quick selection to provide context for input.options
: An array of options for the user to select.default
: The default value will be used if the user enters no other content. It must be one of the option values.
Command
:command
: command to run on variable interpolation.args
: Optional options package passed to the command implementation.
{
"version": "2.0.0"."tasks": [{"label": "ng g"."type": "shell"."command": "ng"."args": ["g"."${input:componentType}"."${input:componentName}"]}],"inputs": [{"type": "pickString"."id": "componentType"."description": "What type of component do you want to create?"."options": [
"component"."directive"."pipe"."service"."class"."guard"."interface"."enum"."enum"]."default": "component"
},
{
"type": "promptString"."id": "componentName"."description": "Name your component."."default": "my-new-component"}}]Copy the code
5. Composite configuration
Compound launch configurations
1. Add the configuration
2. Select the required configuration
Second,Contributes Breakpoints
Debugger breakpoint
The extension lists the language file types that will enable setting breakpoints.
{
"contributes": {
"breakpoints": [{"language": "javascript"
},
{
"language": "javascriptreact"}}}]Copy the code
Three,Contributes Debuggers
1. The attribute
● Type is the unique ID used to identify the debugger in the launch configuration, consistent with type in the launch.json configuration. ● Label is the name of the debugger in VS Code. ● Path to program debug adapter that implements VS Code debug protocol for the actual debugger or runtime. ● Runtime If the path to the debug adapter is not an executable, but runtime is required. ● configurationAttributes is the architecture of the startup configuration parameters specific to this debugger. Note that the JSON schema constructs $ref and definition is not supported. ● initialConfigurations are used to populate the launch configuration of the initial launch.json. ● configurationSnippets can be launched through the configuration used by IntelliSense when editing launch.json. ● Variables introduces replacement variables and binds them to commands implemented by debugger extensions. ● languages Languages in which debugging extensions can be thought of as the “default debugger”.
Example 2.
{
"contributes": {
"debuggers": [{"type": "node"."label": "Node Debug"."program": "./out/node/nodeDebug.js"."runtime": "node"."languages": ["javascript"."typescript"."javascriptreact"."typescriptreact"]."configurationAttributes": {
"launch": {
"required": ["program"]."properties": {
"program": {
"type": "string"."description": "The program to debug."}}}},"initialConfigurations": [{"type": "node"."request": "launch"."name": "Launch Program"."program": "${workspaceFolder}/app.js"}]."configurationSnippets": [{"label": "Node.js: Attach Configuration"."description": "A new configuration for attaching to a running node program."."body": {
"type": "node"."request": "attach"."name": "${2:Attach to Port}"."port": 9229}}]."variables": {
"PickProcess": "extension.node-debug.pickNodeProcess"}}]}}Copy the code
Four,VSCode Debug API
1. The variable
1. activeDebugConsole: DebugConsole
The currently active debug console. If there is no active debug session, output sent to the debug console is not displayed.
2. activeDebugSession: DebugSession | undefined
Debug session that is currently active. If no debug session is activated, the value is undefined.
3. breakpoints: readonly Breakpoint[]
Breakpoint list
2. The event
1. onDidChangeActiveDebugSession: Event<DebugSession | undefined>
An event that fires when the active debug session changes, and also when the active debug session changes to undefined.
2. onDidChangeBreakpoints: Event<BreakpointsChangeEvent>
Events that are triggered when a breakpoint set is added, deleted, or changed.
3. onDidReceiveDebugSessionCustomEvent: Event<DebugSessionCustomEvent>
The event that fires when a custom DAP event is received from a debug session.
4. onDidStartDebugSession: Event<DebugSession>
Events that are triggered when a new debug session is started.
5. onDidTerminateDebugSession: Event<DebugSession>
Events that are triggered when a debug session terminates.
Method 3.
1. addBreakpoints(breakpoints: readonly Breakpoint[]): void
Add a breakpoint
parameter | describe |
---|---|
breakpoints: readonly Breakpoint[] |
Added breakpoint |
2. asDebugSourceUri(source: DebugProtocolSource, session? : DebugSession): Uri
Converts a source descriptor object received through the Debug Adapter Protocol into a Uri that can be used to load its content.
parameter | describe |
---|---|
source: DebugProtocolSource |
Conforms to those defined in the debug adapter protocolSource Object of type. |
session? : DebugSession |
Optional debug session. |
The return value | |
Uri |
One that can be used to load source contenturi . |
3. registerDebugAdapterDescriptorFactory(debugType: string, factory: DebugAdapterDescriptorFactory): Disposable
Registers a debug adapter descriptor function for a specific debug type. Extension is only allowed to register a DebugAdapterDescriptorFactory extension defined debugging type. Otherwise an error will be thrown. For debugging type register multiple DebugAdapterDescriptorFactory can lead to errors.
parameter | describe |
---|---|
debugType: string |
Registers the debug type of the function. |
factory: DebugAdapterDescriptorFactory |
The function to register. |
The return value | |
Disposable |
4. registerDebugAdapterTrackerFactory(debugType: string, factory: DebugAdapterTrackerFactory): Disposable
Registers a debug adapter tracer function for the given debug type.
parameter | describe |
---|---|
debugType: string |
Registers the debug type of the function. |
factory: DebugAdapterTrackerFactory |
The function to register. |
The return value | |
Disposable |
5. registerDebugConfigurationProvider(debugType: string, provider: DebugConfigurationProvider, triggerKind? : DebugConfigurationProviderTriggerKind): Disposable
Register a Debug Configuration Provider for a specific debug type.
parameter | describe |
---|---|
debugType: string |
Debug type. |
provider: DebugConfigurationProvider |
registereddebug configuration provider |
triggerKind? : DebugConfigurationProviderTriggerKind |
|
The return value | |
Disposable |
6. removeBreakpoints(breakpoints: readonly Breakpoint[]): void
Remove breakpoints
parameter | describe |
---|---|
breakpoints: readonly Breakpoint[] |
Deleted breakpoints |
7. startDebugging(folder: WorkspaceFolder | undefined, nameOrConfiguration: string | DebugConfiguration, parentSessionOrOptions? : DebugSession | DebugSessionOptions): Thenable<boolean>
Start debugging by using named startup or named composite configuration or by passing DebugConfiguration directly.
parameter | describe |
---|---|
`folder: WorkspaceFolder | undefined` |
`nameOrConfiguration: string | DebugConfiguration` |
`parentSessionOrOptions? : DebugSession | DebugSessionOptions` |
The return value | |
Thenable<boolean> |
8. stopDebugging(session? : DebugSession): Thenable<void>
Stops the given debugging session, or all debugging sessions if omitted.
parameter | describe |
---|---|
session? : DebugSession |
Debug session |
The return value | |
Thenable<boolean> |
Five,Debugging Architecture
Debugging architecture
1. Debug Adapter
VS Code
Implements a general-purpose (language independent) debuggerUI
It is based on an abstract protocol. Because debuggers typically do not implement this protocol, some mediation is needed to “tune” the debugger to the protocol. This mediation is usually a separate process that communicates with the debugger.We call this mediation a debug adapter for shortDA
.Debug Adapter
),DA
和 VS Code
The abstract protocol used is the Debug adapter protocol (abbreviatedDAP
.Debug Adapter Protocol
). Because the debug adapter protocol is independentVS Code
Yes, it has its ownWeb site.
Because debug adapters are independent of VS Code and can be used in other development tools, they do not match VS Code’s extensibility architecture based on extensions and contribution points.
For this reason, VS Code provides a contribution point where debuggers, debug adapters, can contribute under a particular debug type (such as Node for the Node.js debugger). When the user starts this type of debug session, VS Code starts the registered DA.
Thus, in its most basic form, a debugger extension is just a declarative contribution to the debug adapter implementation, while an extension is basically a package for the debug adapter without any additional code.
2. Demo
Vscode-mock-debug github address: github.com/Microsoft/v…
1. clone
Come down,yarn
The installationnode_modules
2. Open the folderpackage.json
file
The file is configuredbreakpoints
和 debuggers
Two parameters. With the above attribute parsing we know that this plug-in sets the language type tomarkdown
且 type
A value ofmock
One of thedebuggers
3. F5
Launch the plug-in or click on the leftDebug
button
You can seelaunch.json
Configuration in the file.
4. Click leftDebug
button
You can see up hereselect
There’s one in the boxDebug readme.md
, and then start to seemarkdown
The file is under debugging.
5. Close what you just openedvs code
Go back toclone
The project,breakpoints
和 debuggers
To add the new configuration.
debuggers
configurationmockJs
Just follow the abovemock
The configuration is copied and then modifiedtype
和 configurationSnippets
中 label
Can. The configuration is as follows:
{
"type": "mockJs"."languages": ["javascript"]."label": "Mock Debug Js"."program": "./out/debugAdapter.js"."runtime": "node"."configurationAttributes": {
"launch": {
"required": [
"program"]."properties": {
"program": {
"type": "string"."description": "Absolute path to a text file."."default": "${workspaceFolder}/${command:AskForProgramName}"
},
"stopOnEntry": {
"type": "boolean"."description": "Automatically stop after launch."."default": true
},
"trace": {
"type": "boolean"."description": "Enable logging of the Debug Adapter Protocol."."default": true
},
"compileError": {
"type": "string"."description": "Simulates a compile error in 'launch' request."."enum": [
"default"."show"."hide"]."enumDescriptions": [
"default: show fake compile error to user"."show fake compile error to user"."do not show fake compile error to user"}}}},"initialConfigurations": [{"type": "mockJs"."request": "launch"."name": "Ask for file name"."program": "${workspaceFolder}/${command:AskForProgramName}"."stopOnEntry": true}]."configurationSnippets": [{"label": "Mock Debug Js: Launch"."description": "A new configuration for 'debugging' a user selected js file."."body": {
"type": "mockJs"."request": "launch"."name": "Ask for file name"."program": "^\"\\${workspaceFolder}/\\${command:AskForProgramName}\""."stopOnEntry": true}}]."variables": {
"AskForProgramName": "extension.mock-debug.getProgramName"}}Copy the code
6. After the configuration, clicksampleWorkspace
Create in folderindex.js
File, write code.
7. Click on the leftDebug
Button, selectExtension + Server
Option and start debugging
8. In the newly opened windowlaunch.json
File, clickAdd Configuration...
Button, selectMock Debug Js: Launch
And modify the configuration
{
"type": "mockJs"."request": "launch"."name": "Debug js"."program": "${workspaceFolder}/index.js"."stopOnEntry": true
}
Copy the code
9. Click on theDebug
Button, selectDebug js
options
You can debugjs
file