📜 ⬆️ ⬇️

Debugging Node.js in Visual Studio

I like Node.js, but recently I started using it on serious projects. At the same time, I continued to use my favorite development environment * . And if for simple scripts it’s enough just an editor, then for serious development you need serious tools, in particular, a debugger. I couldn’t find anything ready for the studio, so I took it and made it myself for a couple of days off:
image

Quick start


Install Node.js and NodeVsDebugger extension. You can also install it from the extension gallery: Alt + T, U select Online , enter “node debug” in the search and click download .
Next, open the js-document, set breakpoint, press Ctrl + E, Ctrl + D, voila!

What is already done



Debugging projects
At the moment, debugging projects is bolted in the form of a crutch, and you can debug in a node almost any project, be it a web site, a web application, or generally C # or C ++ makefile project. To do this, you must first configure our debugger, in the menu Debug → Node.js Debugging, or simply by pressing Alt + D, E, C.
I did not have time to make a normal UI for settings, so now they are just a JSON file (with comments). In the comments at the beginning of the file describes the available settings and what they mean. They are saved to a file named ".nodevsdbg" in the root of the website or next to the project file.
After the settings are made, you can launch the debugger using Ctrl + E, Ctrl + A. I recommend zabindid on this command the F5 key, and then for projects where there are no settings for the node debugger, or it is turned off in the config (mode = "off"), the standard debugger will be launched.
Naturally, I plan then to make a nodejs-project that will be assigned a custom debugger, and all these crutches will not be needed.

Debugging on a remote host
You can also debug a node running on another host, for example, on a virtual machine with Linux. In one way or another, it is enough to forward the remote port and set it in the settings. Example for PuTTY:
image
')

What is not enough



Part of these features I plan to finish soon. But since I do it sometimes in the evenings, I will be glad to any help - the code is open, send pull requests .

How was it done


The node already has a ready backend for the debugger, which can be reached by simply connecting via an http-like protocol to port 5858 (by default). The protocol is based on messaging in JSON-format. The protocol itself is not node-specific, but inherited from the V8 engine. A brief description can be found here . This document is enough for an initial acquaintance, however, as it turned out later, it is full of mistakes, understatement, and stupid typos.
In the studio there is a ready-made good GUI for debugger. Naturally, I decided not to reinvent the wheel, but simply connected these two parts. The interfaces and concepts of both parts are quite similar, because it is hard to invent something new. In the V8 protocol, there are control commands for the process being debugged (Break, Go, Step), there is a poll of the current state (Stacktrace aka Backtrace), there are some methods for viewing variables, expressions and executing code pieces. And a lot of other things ...

What problems I encountered:
- At the first attempt to debug the http-server, I ran into a debugger freeze at each debugging step. The kilometer backtrace, caused by the cunning serialization (it is called a mirror ), which tries to serialize the Buffer with a separate descriptive object for each buffer byte, is to blame. This was fixed by including inlineRefs.
- By default, the lines are abbreviated, as in the following screenshot. There is nothing wrong with this, since the whole string can also be viewed: at the user's request, we follow the string with maxStringLength = -1
image
All this can be understood by looking at debug-debugger.js in the same place you can see other commands that are not described in the document on the wiki.
- On the studio side, the problem was the lack of adequate examples on the Custom Debug Engine. I did not have time for a detailed study of the documentation in MSDN (and there are 100,500 interfaces, structures, enums, etc.), although in the end I often glanced there. The only official example is an unpretentious native C debugger written for an old studio, automatically converted into a studio project 2010. It consists of a large piece of managed C ++, which we do not need. And, actually, the wrappers above the studio interfaces written in the days of C # 2.0 are terribly wordy.
- I redid the registration of the engine, and twice. In the example, the registration of the engine was made old regsvr32 "mixed-mode C + + assembly". We got rid of this assembly, and I made the registration just by explicitly adding keys to the registry. But with the registration, too, it wasn’t that simple, with 2012 ’s studios having a little changed places where she is looking for debugging engines. In the end, all by itself was treated when I made a package for debugger and added RegistrationAttribute to it .
- Leapfrog with the name of buttons, menu items and commands. This article helped to understand.
- Instead of the standard library for parsing / serializing JSON, I took Newtonsoft.Json. I like it better, and it works faster.

Instead of an afterword


Download, try, write (good) reviews on the extension page )
Bugs, please send to githab .
Better yet, send pull requests directly to the code — fork me on GitHub! .

Source: https://habr.com/ru/post/172107/


All Articles