UNPKG

chrome-devtools-frontend

Version:
120 lines (91 loc) 5.97 kB
# Resource management in DevTools This document outlines how DevTools keeps track of resources like scripts and HTML files, and how they interact with other features such as the Debugger. The source code lives in the bindings/, persistence/ and workspace/ directories. ## Core concepts and classes * **Project:** Interface to a collection of resources. DevTools supports different project **types**. For example “filesystem”, for resources originating from the developers local machine, and “network”, for actual page resources. The **Project** interface abstracts away rudimentary file operations. Depending on the **type**, a **Project** may be able to create, rename or delete resources, or change the contents. * **Workspace**: A collection of all the **Projects** currently in use. Implemented as a singleton in WorkspaceImpl.ts. * **UISourceCode:** An actual resource identified by its URL. Scripts and stylesheets are prominent examples, but DevTools also uses more esoteric **ResourceTypes** such as XHR, WebSocket or EventSource. ## Project types A short overview over the different Project types and what **kind of resources** they contain. * **Network:** All resources loaded from the network are stored in network projects. Different targets and/or **Resource** **types** may use different projects. E.g. Each target has their own project containing only JavaScript source maps. * **Filesystem:** Resources stored on the developers local machine. * Snippets are managed with a single Project just for snippets. * Each local directory mapped into DevTools with the “Workspaces” feature has its own project. * Each directory used for the “Overrides” feature has a corresponding project to manage the local files. * **Formatter:** A single project of this type manages the formatted version of script resources. That is the “pretty-print” feature for minified JS files. * **ContentScripts**: Scripts from extensions running in the context of the page itself. One project per target. Source maps for content scripts are managed by separate, per target, projects. The source map projects also have the **ContentScripts** type. * **Service:** One project of this type per target. It holds placeholder UISourceCodes for source maps while they are loaded. Once a source map finishes loading, the placeholder is removed from the **Service** project. * **Debugger:** One project of this type per target. Debugger projects store parsed JS scripts (see next section). ## The “Debugger” project type When V8 parses scripts, it sends out a [“Debugger.ScriptParsed”](https://chromedevtools.github.io/devtools-protocol/tot/Debugger/#event-scriptParsed) event with some details, including a unique script ID and the URL of the script. For each “Debugger.ScriptParsed” event, DevTools creates a **Script** object and an associated **UISourceCode** in the “debugger” project. It is important to note that the URL of this “debugger” UISourceCode contains both the script ID as well as the script name (not URL!) to uniquely identify it. This is because: _The relationship between network/filesystem UISourceCodes and **Script** **objects**/debugger UISourceCodes is 1:n._ For example if the same script is included twice on a page with <script> elements, it will result in a single UISourceCode in the **Network** project but **two Script** **objects** and two UISourceCodes in the **Debugger** project. Similarly, every invocation of a Snippet will result in a separate **Script** object per invocation while the Snippet itself is stored in a **Filesystem** project. ## Mappings and bindings As can be seen above, UISourceCodes in different projects can potentially be related to one another. A minified script resource in a **scripts Network project** might have a pretty-printed version in the **Formatter project** while the source map for the minified script is stored in the **source map Network project**. Once the minified script is parsed/executed by V8, it also has a corresponding **Script object** and a UISourceCode in the **Debugger project**. This brings us to mappings and bindings. The terminology is roughly: * _A **binding** ties different UISourceCodes together and determines which UISourceCodes relate to one another._ * _A **mapping** translates source positions between bound UISourceCodes._ ## Binding implementations There are a couple of classes tasked with establishing bindings between UISourceCodes: * **DebuggerWorkspaceBinding:** Responsible for scripts and source maps. It ties together network/filesystem UISourceCodes with **Script** objects and the debugger USourceCodes. Script source maps are also partially implemented by this class. * **CSSWorkspaceBinding:** Responsible for CSS and CSS source maps. DevTools can handle source mapped CSS when it was authored in SASS and this class is responsible for binding the corresponding UISourceCodes. * **PersistenceBinding/PersistenceImpl/Automapping**: Responsible for the [“Workspaces”](https://developer.chrome.com/docs/devtools/workspaces/) feature. When a developer adds a local directory to DevTools that corresponds to the pages sources, these classes establish and manage the binding between the corresponding **Filesystem** and **Network** resources. * **NetworkPersistenceManager**: Responsible for the [“Local Overrides”](https://developer.chrome.com/blog/new-in-devtools-65/#overrides) feature. It connects the **Network** resources with the corresponding overwritten version in a **Filesystem** project. This class also handles network request interceptions and determines whether to serve the original or the overwritten UISourceCode. Please keep in mind that many of these classes have gathered additional responsibilities over the years, so the concepts presented above might not always cleanly apply or be apparent in code.