如何实现DebugProgramRunner以连接Node.js调试进程?
Hey there! Let's walk through how to implement your DebugProgramRunner and pick the right VmConnection for your Node.js debugging setup.
Implementing DebugProgramRunner to Connect to the Node Process
Since you're already starting the Node process with node --inspect-brk=30000 example.js via your NodeJSDebuggableConfiguration's createDebugProcess method, here's how to tie in the DebugProgramRunner to establish the debug connection:
- First, create a class that implements
DebugProgramRunner(or extendsDebugProgramRunnerBaseto skip common boilerplate). Override thecanRunmethod to returntrueonly when the configuration is yourNodeJSDebuggableConfigurationtype—this ensures your runner is only used for your specific Node.js setups. - In the
runmethod, you'll need to:- Retrieve the
DebugEnvironmentfrom the input parameters. This gives you access to your configuration and process info. - Fetch the debug process you've already initialized via
createDebugProcess. - Wait for the Node process to be ready to accept debug connections. Since you're using
--inspect-brk, the process pauses immediately and listens on port 30000. You can add a short delay or run a quick port-check to avoid race conditions. - Use IDEA's debugger API to attach to the Node VM. Leverage
DebuggerManagerEx.getInstance()to get the debugger manager, then initiate the connection using the appropriate WebSocket endpoint.
- Retrieve the
Here's a simplified code snippet to illustrate:
public class NodeJSDebugProgramRunner extends DebugProgramRunnerBase { @Override public boolean canRun(@NotNull String executorId, @NotNull RunProfile profile) { return profile instanceof NodeJSDebuggableConfiguration; } @Override protected void run(@NotNull RunProfileState state, @NotNull ExecutionEnvironment env) throws ExecutionException { if (!(state instanceof NodeJSDebugState)) { return; } NodeJSDebugState debugState = (NodeJSDebugState) state; DebugProcess debugProcess = debugState.getDebugProcess(); // Wait for debug port to be available (add proper error handling in production) try { Thread.sleep(1000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new ExecutionException("Failed to wait for debug port", e); } // Attach to Node VM via WebSocket DebuggerManagerEx debuggerManager = DebuggerManagerEx.getInstanceEx(env.getProject()); WebSocketVmConnection connection = new WebSocketVmConnection(debuggerManager.getProject(), new URI("ws://localhost:30000")); debuggerManager.attachVirtualMachine(connection, debugProcess); } }
Choosing the Right VmConnection for Node.js WebSocket Debugging
Node.js uses the Chrome DevTools Protocol (CDP) over WebSocket for debugging, so you'll want a WebSocket-based VmConnection implementation.
In IDEA's debugger framework, the appropriate class is typically WebSocketVmConnection (or a specialized subclass like ChromeVmConnection tailored for Node/Chrome debugging). This class handles all the WebSocket communication details—framing messages, managing connection lifecycle, and translating between IDEA's debugger API and the CDP protocol.
Key notes:
- When instantiating the connection, use the exact WebSocket URL exposed by Node.js. For
--inspect-brk=30000, this URL isws://localhost:30000. - Make sure to register listeners for connection open/close events, and handle protocol messages (like setting breakpoints or stepping through code) via IDEA's debugger utilities.
If you don't find a pre-built WebSocketVmConnection, you can implement a custom one by extending VmConnection and using Java's WebSocket API (or IDEA's internal WebSocket tools) to handle the underlying communication.
内容的提问来源于stack exchange,提问作者Yang Chen

