As a front-end developer, debugging is a concept that is exposed to every day. What do you think debugging is?

Some students said that I use Chrome DevTools to debug web pages, you can view elements, network requests, breakpoints run JS, use Performance tools to analyze performance, etc. This is the debugging of web pages.

A classmate said that I use VSCode Debugger to debug Node.js, and I can debug the code of multiple processes at the same time. This is a debugging of Node.js.

Some students said that I use React DevTools and Vue DevTools chrome plugins to debug React, Vue components, and also use independent React DevTools to debug React Native applications. This is my usual debugging tool.

Yes, these are all debugging. So what do they have in common?

They are all exposing the running state to the debugging tool for some demonstration and interaction.

So, we can give the following definition of debugging:

The code runs on a certain platform, exposes the runtime state in some way, passes it to the development tool for UI display and interaction, assists developers in troubleshooting problems, combing through processes, understanding the code running state, etc. This is debugging.

A certain platform here can be a browser, Node.js, Electron, Mini Programs and any other platform that can execute JS code.

The exposed runtime state may be the call stack, the execution context, or the structure of the DOM, the state of the React component, and so on.

This data is generally exposed through WebSocket-based debugging protocols, but there are other ways to do so.

So how are common debugging tools implemented, and are there any general principles?

Let’s take a look at them separately:

Chrome DevTools is divided into two parts, backend and frontend:

Backend and Chrome integration are responsible for exposing Chrome’s web runtime state through debugging protocols.

The frontend is independent and responsible for docking debugging protocols and doing UI presentation and interaction.

The debugging protocol between the two is called the Chrome DevTools Protocol, or CDP for short.

The way to transfer protocol data is called a message channel, and there are many ways, such as when Chrome DevTools are embedded in Chrome, the two communicate through global functions; When Chrome DevTools remotely debugs the code of a target, the two communicate through a WebSocket.

Frontend, backend, Debug Protocol (CDP), channel, these are the 4 components of Chrome DevTools.

The backend can be Chromium, Node.js, or V8, and the JS runtime supports the Chrome DevTools Protocol.

This is how Chrome DevTools is debugged.

In addition to Chrome DevTools, VSCode Debugger is also a commonly used debugging tool:

The principle of VSCode Debugger is similar to that of Chrome DevTools, which is also divided into frontend, backend, and debugging protocols, except that it has an additional layer of adapter protocols.

In order to be able to debug Node.js code directly with Chrome DevTools, Node.js 6 or above uses the Chrome DevTools Protocol as a debugging protocol, so VSCode Debugger debugger debugs Node.js also through this protocol.

But there is an additional layer of adapter protocol Debug Adapter Protocol in the middle, why?

Because VSCode is not a JS-specific editor, it may be used to debug Python code, Rust code, etc., naturally it cannot be deeply coupled with the debugging protocol of a certain language, so there is an additional adapter layer.

This allows VSCode Debugger to debug code in various languages with the same set of UI and logic, as long as it is translated into protocols with different Debug apapters.

This has the added benefit that other editors can also use this Debug Adapter Protocol for debugging, so that the various languages of VSCode can be directly reused with the Debug Adapter of VSCode.

The UI part of VSCode Debugger is considered frontend, and the target language of debugging is considered the backend part, and the debugging protocol is also passed through WebSocket.

The overall debugging principle is similar to that of Chrome DevTools, except that in order to support the cross-language reuse of frontend, there is an additional layer of adapters.

In addition to Chrome DevTools and VSCode Debugger, we usually use Vue DevTools and React DevTools when we develop Vue or React applications:

Vue DevTools or React DevTools both exist in the form of Chrome Extensions, and to understand how they work, you need to understand the mechanisms of Chrome plugins.

The part of the Chrome plugin that can access the DOM of the web page is called Content Script, which takes effect when the page starts, and you can write some logic to manipulate the DOM. There is also a part of the background running, called Background, the browser starts to take effect, the life cycle is relatively long, you can do some resident logic.

If it is a Chrome plugin that extends DevTools, there is also a part of the DevTools Page, which is the page displayed in DevTools:

The Content Script section operates the DOM and listens to DOM Events.

The Backgroud section has access to extension APIs and can communicate with Content Script and DevTools Page.

The DevTools Page section has access to devtools APIs and can inject JS execution into the current window.

This is the approximate architecture of the Chrome plugin.

Vue DevTools and React DevTools are debugging capabilities based on this architecture.

If you look at the source directory of Vue DevTools, you will see that it is also divided into backend and frontend

So where does the backend run, where does the frontend run, and how do the two communicate?

DevTools Page is available in the page eval JS, which can inject backend code.

The backend code can get the information of the Vue component and pass it to the background through a window message.

Background can communicate with DevTools Page for message forwarding.

DevTools Page renders component information and implements interactive functions based on the data obtained.

React DevTools is similar, taking component information through backend and then passing it to DevTools Page for rendering and interaction.

However, React DevTools also has a separate Electron application that can be used for debugging React Native.

Is this custom debugging tool also using the Chrome DevTools Protocol protocol?

Obviously not, CDP protocol for debugging DOM, JS, etc. is very good, but not good to extend, if there are other requirements, generally are custom debugging protocol.

After going through the principles of Chrome DevTools, VSCode Debugger, and Vue/React DevTools, have you found that they have some similarities?

Yes, there are backend parts responsible for getting runtime information, frontend parts for rendering and interaction, debugging protocols to specify the format of different data, and different channels, such as WebSocket, background forwarding of Chrome plugins, etc.

Frontend, backend, debugging protocol, channel, these are the four elements of debugging tools.

However, different debugging tools will have different designs, such as VSCode Debugger in order to cross-language reuse, an additional layer of Debugger Adapter, React DevTools has a separate electron application, with a custom debugging protocol, you can debug React Native code.

We use Chrome DevTools, VSCode Debugger, Vue/React DevTools and other tools to debug web pages, Node.js, React/Vue code, all of which are debugging tools.

Debugging is to pass runtime information to the development tool through some kind of channel (such as WebSocket), do UI display and interaction, and assist developers in troubleshooting problems and understanding the running status of code.

We briefly went through the principles of these debugging tools:

They have common parts, all of which are frontend, backend, debugging protocol, and channel.

There are also different parts, such as VSCode Debugger has an extra layer of Debugger Adapter for cross-language reuse, Vue/React DevTools by injecting backend code into the page, and then implementing two-way communication through the background.

By grasping the same parts of them to analyze and understand the design reasons for the different parts, it is easy to understand the principles of various debugging tools.