devtools.ts
Overview
The devtools.ts file is a utility module within the SWR (stale-while-revalidate) data fetching library ecosystem that enables integration with developer tools specifically designed for inspecting and debugging SWR hooks and their internal state.
Its primary purpose is to:
Detect if SWR devtools integration is enabled in the current environment.
Expose a hook interface from the global
windowobject that SWR internals or external devtools extensions can consume.Provide a setup function that injects the React instance into the global scope, allowing devtools UI components to render and interact with React internals properly.
This file operates as a lightweight, conditional bridge between the SWR library and an external devtools environment, facilitating real-time inspection of SWR cache, lifecycle events, mutations, and revalidations during development without affecting production performance.
Detailed Explanation
Imported Dependencies
React(from'react'): The React library instance is imported to be exposed globally for devtools usage.isWindowDefined(from'./helper'): A utility boolean that checks if the globalwindowobject is available (i.e., code is running in a browser environment).
Constants and Exports
enableDevtools: boolean
const enableDevtools = isWindowDefined && window.__SWR_DEVTOOLS_USE__
Purpose: Determines if the devtools integration should be enabled.
Logic: Checks if the code is running in a browser (
isWindowDefined) and if the globalwindowobject contains a truthySWR_DEVTOOLS_USEproperty.Type:
boolean(with TypeScript's@ts-expect-errorto suppress type checking on the dynamic window property).
use: any[]
export const use = enableDevtools
? // @ts-expect-error
window.__SWR_DEVTOOLS_USE__
: []
Purpose: Exports an array that acts as the devtools hook interface.
Behavior:
If devtools are enabled, it exports the array referenced by
window.SWR_DEVTOOLS_USE. This array contains devtools hooks or listeners that SWR internals or external devtools extensions subscribe to.If not enabled, exports an empty array to avoid runtime errors and ensure safe fallback.
Type: An array (likely of hooks or function references).
Functions
setupDevTools(): void
export const setupDevTools = () => {
if (enableDevtools) {
// @ts-expect-error
window.__SWR_DEVTOOLS_REACT__ = React
}
}
Purpose: Prepares the devtools environment by exposing the React instance globally.
Parameters: None.
Returns: Nothing (
void).Behavior:
When called, and if devtools integration is enabled, it sets the global
window.SWR_DEVTOOLS_REACTproperty to the imported React instance.This is necessary to allow devtools UI components to render React elements and hook into React internals correctly.
Usage: Typically invoked during the initialization phase of SWR or the application to ensure devtools have access to the React instance.
Usage Examples
import { use, setupDevTools } from './devtools'
// During app or SWR initialization
setupDevTools()
// Access the devtools hooks (if enabled)
if (use.length > 0) {
use.forEach((hook) => {
// Register or invoke devtools hooks
})
}
In typical SWR usage, this module is abstracted away and consumed internally by SWR core or middleware components. External devtools extensions also listen to the global window.__SWR_DEVTOOLS_USE__ array to hook into SWR events.
Implementation Details and Algorithms
Conditional Exposure: The file avoids polluting the global namespace or incurring overhead by conditionally enabling devtools only if the environment supports it.
Global Hook Array: By referencing a global array
window.SWR_DEVTOOLS_USE, the file allows multiple devtools hooks or listeners to be registered dynamically.React Injection: Exposing the React instance globally (
window.SWR_DEVTOOLS_REACT) is a crucial step that enables devtools components (which may render React elements) to function correctly without bundling React separately.TypeScript Suppressions: The use of
@ts-expect-errorannotations indicates that the file accesses dynamic properties on thewindowobject that TypeScript cannot verify at compile time, which is common for global hooks or flags injected at runtime.
Interaction with Other Parts of the System
SWR Core and Middleware: The SWR hook implementations check and interact with the
useexported from this file to register lifecycle events, cache updates, and mutations to the devtools system.Devtools Extensions / Browser Plugins: External devtools UI components or browser extensions listen on the global
window.SWR_DEVTOOLS_USEarray to receive SWR event data for display and debugging.React Components: The React instance exposed globally is used by devtools to render React-based inspection panels or overlays.
Helper Module (
helper.ts): TheisWindowDefinedutility ensures this module behaves correctly in server-side rendering (SSR) scenarios by preventing access to thewindowobject when it is undefined.
Mermaid Diagram: File Structure and Workflow
flowchart TD
A[Start: Import React & helper] --> B{Is window defined?}
B -->|No| C[enableDevtools = false]
B -->|Yes| D{window.__SWR_DEVTOOLS_USE__ exists?}
D -->|No| C
D -->|Yes| E[enableDevtools = true]
E --> F[Export use = window.__SWR_DEVTOOLS_USE__]
C --> G[Export use = []]
H[Call setupDevTools()] --> I{enableDevtools?}
I -->|Yes| J[Set window.__SWR_DEVTOOLS_REACT__ = React]
I -->|No| K[Do nothing]
style A fill:#f9f,stroke:#333,stroke-width:1px
style B fill:#bbf,stroke:#333,stroke-width:1px
style D fill:#bbf,stroke:#333,stroke-width:1px
style I fill:#bbf,stroke:#333,stroke-width:1px
The flowchart shows the conditional logic for enabling devtools based on global flags.
It visualizes exporting the devtools hook array or an empty array.
It shows the setup process that globally exposes React for devtools usage.
Summary
The devtools.ts file is a critical utility module that enables the SWR library to integrate with developer tools. It does so by:
Detecting devtools availability through global window flags.
Exporting a hook interface array for internal and external devtools consumption.
Providing a setup function that exposes the React instance globally for devtools rendering.
This module is designed to be lightweight and non-intrusive, activating only in development or special debugging environments, and thus avoiding any performance penalties in production builds. It forms the backbone of the SWR developer experience by allowing real-time inspection and debugging of SWR hooks, cache, and lifecycle events.