├── .nvmrc ├── .node-version ├── packages ├── playground │ ├── react17-scss │ │ ├── .nvmrc │ │ ├── src │ │ │ ├── pages │ │ │ │ └── Theme.tsx │ │ │ ├── App.tsx │ │ │ ├── main.tsx │ │ │ └── components │ │ │ │ └── Layout.tsx │ │ ├── .gitignore │ │ ├── index.html │ │ ├── tsconfig.json │ │ ├── vite.config.ts │ │ └── package.json │ ├── react17-webpack4 │ │ ├── .nvmrc │ │ ├── src │ │ │ ├── pages │ │ │ │ └── Theme.jsx │ │ │ ├── App.jsx │ │ │ ├── main.jsx │ │ │ └── components │ │ │ │ └── Layout.jsx │ │ ├── .gitignore │ │ ├── public │ │ │ └── index.html │ │ ├── tsconfig.json │ │ ├── package.json │ │ └── webpack.config.js │ ├── react │ │ ├── src │ │ │ ├── pages │ │ │ │ └── Theme.tsx │ │ │ ├── App.tsx │ │ │ └── main.tsx │ │ ├── tsconfig.json │ │ ├── index.html │ │ ├── package.json │ │ └── vite.config.ts │ ├── react-webpack │ │ ├── src │ │ │ ├── pages │ │ │ │ └── Theme.jsx │ │ │ ├── App.jsx │ │ │ ├── main.jsx │ │ │ └── plugins │ │ │ │ └── MyPlugin.jsx │ │ ├── public │ │ │ └── index.html │ │ ├── package.json │ │ ├── README.md │ │ └── webpack.config.js │ ├── umi │ │ ├── .gitignore │ │ ├── plugin.ts │ │ ├── src │ │ │ ├── app.tsx │ │ │ ├── global.less │ │ │ ├── layouts │ │ │ │ └── index.tsx │ │ │ └── pages │ │ │ │ ├── index.less │ │ │ │ ├── index.tsx │ │ │ │ └── about.less │ │ ├── typings.d.ts │ │ ├── package.json │ │ ├── .umirc.ts │ │ └── tsconfig.json │ ├── react19 │ │ ├── tsconfig.json │ │ ├── index.html │ │ ├── src │ │ │ ├── main.tsx │ │ │ ├── style.css │ │ │ └── App.tsx │ │ ├── vite.config.ts │ │ └── package.json │ ├── my-devtools-play │ │ ├── src │ │ │ ├── main.tsx │ │ │ └── App.tsx │ │ ├── index.html │ │ ├── vite.config.ts │ │ ├── package.json │ │ └── tsconfig.json │ └── my-devtools │ │ ├── package.json │ │ ├── tsconfig.json │ │ ├── tsup.config.ts │ │ └── src │ │ ├── index.ts │ │ └── plugins │ │ └── index.ts ├── react-devtools-ui │ ├── src │ │ ├── components │ │ │ ├── Tag │ │ │ │ ├── index.ts │ │ │ │ └── Tag.tsx │ │ │ ├── Select │ │ │ │ ├── index.ts │ │ │ │ ├── Select.tsx │ │ │ │ └── Select.module.css │ │ │ ├── Switch │ │ │ │ ├── index.ts │ │ │ │ └── Switch.tsx │ │ │ ├── Checkbox │ │ │ │ ├── index.ts │ │ │ │ ├── Checkbox.tsx │ │ │ │ └── Checkbox.module.css │ │ │ ├── Card │ │ │ │ ├── index.ts │ │ │ │ ├── Card.module.css │ │ │ │ └── Card.tsx │ │ │ ├── Badge │ │ │ │ ├── index.ts │ │ │ │ ├── Badge.module.css │ │ │ │ └── Badge.tsx │ │ │ ├── Input │ │ │ │ ├── index.ts │ │ │ │ └── Input.tsx │ │ │ ├── Button │ │ │ │ ├── index.ts │ │ │ │ └── Button.tsx │ │ │ └── index.ts │ │ ├── types.d.ts │ │ ├── index.ts │ │ ├── theme │ │ │ └── types.ts │ │ └── styles │ │ │ └── base.css │ ├── tsconfig.node.json │ ├── tsconfig.json │ ├── package.json │ └── vite.config.ts ├── react-devtools │ ├── src │ │ ├── scan.ts │ │ ├── config │ │ │ └── index.ts │ │ ├── utils │ │ │ └── index.ts │ │ ├── shims.d.ts │ │ ├── overlay.ts │ │ ├── integrations │ │ │ └── index.ts │ │ ├── middleware │ │ │ ├── client-server.ts │ │ │ ├── index.ts │ │ │ ├── plugins.ts │ │ │ └── open-in-editor.ts │ │ ├── compat │ │ │ └── index.ts │ │ ├── codegen │ │ │ ├── index.ts │ │ │ ├── devtools-hook.ts │ │ │ └── config-injector.ts │ │ ├── dir.ts │ │ ├── webpack.ts │ │ ├── vite.ts │ │ ├── umi.ts │ │ └── index.ts │ ├── tsconfig.json │ ├── README.md │ ├── package.json │ └── client │ │ └── index.html ├── react-devtools-kit │ ├── src │ │ ├── messaging │ │ │ ├── types │ │ │ │ ├── index.ts │ │ │ │ └── channel.ts │ │ │ └── presets │ │ │ │ ├── iframe │ │ │ │ ├── context.ts │ │ │ │ ├── client.ts │ │ │ │ └── server.ts │ │ │ │ ├── index.ts │ │ │ │ └── broadcast │ │ │ │ ├── client.ts │ │ │ │ └── server.ts │ │ ├── index.ts │ │ └── core │ │ │ ├── index.ts │ │ │ └── open-in-editor │ │ │ └── index.ts │ ├── tsconfig.json │ ├── tsdown.config.ts │ └── package.json ├── shared │ ├── src │ │ ├── index.ts │ │ ├── constants.ts │ │ └── env.ts │ ├── README.md │ ├── tsdown.config.ts │ └── package.json ├── react-devtools-overlay │ ├── src │ │ └── composables │ │ │ ├── useOverlay.ts │ │ │ └── usePanelVisible.ts │ ├── tsconfig.json │ └── package.json ├── react-devtools-client │ ├── src │ │ ├── components │ │ │ ├── graph │ │ │ │ ├── index.ts │ │ │ │ └── GraphNavbar.tsx │ │ │ └── assets │ │ │ │ └── ReactLogo.tsx │ │ ├── global.css │ │ ├── types │ │ │ ├── plugin.ts │ │ │ └── messages.ts │ │ ├── events.ts │ │ ├── composables │ │ │ └── useComponentTreeHook.ts │ │ └── main.tsx │ ├── tsconfig.json │ ├── vite.config.ts │ ├── package.json │ └── index.html ├── react-devtools-core │ ├── src │ │ ├── plugin │ │ │ └── index.ts │ │ ├── index.ts │ │ └── rpc │ │ │ ├── types.ts │ │ │ └── index.ts │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── package.json │ └── examples │ │ └── performance-plugin.ts ├── react-devtools-scan │ ├── tsconfig.json │ ├── tsup.config.ts │ └── package.json └── ui-story │ ├── tsconfig.json │ ├── .storybook │ ├── preview.ts │ └── main.ts │ ├── package.json │ └── stories │ ├── Switch.stories.tsx │ ├── Checkbox.stories.tsx │ ├── Select.stories.tsx │ ├── Card.stories.tsx │ └── Badge.stories.tsx ├── .npmrc ├── docs ├── postcss.config.js ├── public │ ├── screenshots │ │ ├── scan.png │ │ ├── assets.png │ │ ├── modules.png │ │ ├── overview.png │ │ ├── timeline.png │ │ ├── inspector.png │ │ ├── assets-detail.png │ │ ├── scan-detail.png │ │ ├── component-tree.png │ │ ├── timeline-detail.png │ │ └── component-tree-detail.png │ └── favicon.svg ├── metadata.json ├── src │ ├── types.ts │ ├── main.tsx │ ├── pages │ │ ├── index.ts │ │ └── docs │ │ │ └── FAQ.tsx │ ├── components │ │ ├── ui │ │ │ ├── Spotlight.tsx │ │ │ └── Button.tsx │ │ ├── Footer.tsx │ │ └── Stats.tsx │ └── hooks │ │ └── useScrollAnimation.ts ├── vite.config.ts ├── tsconfig.json ├── index.html ├── package.json └── tailwind.config.ts ├── uno.config.ts ├── .editorconfig ├── vitest.config.ts ├── bump.config.ts ├── pnpm-workspace.yaml ├── LICENSE ├── .vscode └── settings.json ├── tsconfig.json ├── eslint.config.ts ├── turbo.json └── .gitignore /.nvmrc: -------------------------------------------------------------------------------- 1 | 20 2 | 3 | -------------------------------------------------------------------------------- /.node-version: -------------------------------------------------------------------------------- 1 | lts-latest 2 | -------------------------------------------------------------------------------- /packages/playground/react17-scss/.nvmrc: -------------------------------------------------------------------------------- 1 | 14.0.0 2 | 3 | -------------------------------------------------------------------------------- /packages/playground/react17-webpack4/.nvmrc: -------------------------------------------------------------------------------- 1 | 14.0.0 2 | 3 | -------------------------------------------------------------------------------- /packages/react-devtools-ui/src/components/Tag/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Tag' 2 | -------------------------------------------------------------------------------- /packages/react-devtools/src/scan.ts: -------------------------------------------------------------------------------- 1 | export * from '@react-devtools-plus/scan' 2 | -------------------------------------------------------------------------------- /packages/react-devtools-kit/src/messaging/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './channel' 2 | -------------------------------------------------------------------------------- /packages/react-devtools-ui/src/components/Select/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Select' 2 | -------------------------------------------------------------------------------- /packages/react-devtools-ui/src/components/Switch/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Switch' 2 | -------------------------------------------------------------------------------- /packages/react-devtools-ui/src/components/Checkbox/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Checkbox' 2 | -------------------------------------------------------------------------------- /packages/shared/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './constants' 2 | export * from './env' 3 | export * from './general' 4 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | shamefully-hoist=true 2 | strict-peer-dependencies=false 3 | side-effects-cache=false 4 | shell-emulator=true 5 | -------------------------------------------------------------------------------- /docs/postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/screenshots/scan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wzc520pyfm/react-devtools-plus/HEAD/docs/public/screenshots/scan.png -------------------------------------------------------------------------------- /packages/react-devtools-overlay/src/composables/useOverlay.ts: -------------------------------------------------------------------------------- 1 | export function getShowHostComponents() { 2 | return false 3 | } 4 | -------------------------------------------------------------------------------- /packages/react-devtools-ui/src/components/Card/index.ts: -------------------------------------------------------------------------------- 1 | export { Card } from './Card' 2 | export type { CardProps } from './Card' 3 | -------------------------------------------------------------------------------- /packages/shared/README.md: -------------------------------------------------------------------------------- 1 | # @react-devtools-plus/shared 2 | 3 | > Internal utility types shared across react-devtools packages. 4 | -------------------------------------------------------------------------------- /docs/public/screenshots/assets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wzc520pyfm/react-devtools-plus/HEAD/docs/public/screenshots/assets.png -------------------------------------------------------------------------------- /docs/public/screenshots/modules.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wzc520pyfm/react-devtools-plus/HEAD/docs/public/screenshots/modules.png -------------------------------------------------------------------------------- /docs/public/screenshots/overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wzc520pyfm/react-devtools-plus/HEAD/docs/public/screenshots/overview.png -------------------------------------------------------------------------------- /docs/public/screenshots/timeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wzc520pyfm/react-devtools-plus/HEAD/docs/public/screenshots/timeline.png -------------------------------------------------------------------------------- /packages/react-devtools-ui/src/components/Badge/index.ts: -------------------------------------------------------------------------------- 1 | export { Badge } from './Badge' 2 | export type { BadgeProps } from './Badge' 3 | -------------------------------------------------------------------------------- /packages/react-devtools-ui/src/components/Input/index.ts: -------------------------------------------------------------------------------- 1 | export { Input } from './Input' 2 | export type { InputProps } from './Input' 3 | -------------------------------------------------------------------------------- /docs/public/screenshots/inspector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wzc520pyfm/react-devtools-plus/HEAD/docs/public/screenshots/inspector.png -------------------------------------------------------------------------------- /packages/react-devtools-ui/src/components/Button/index.ts: -------------------------------------------------------------------------------- 1 | export { Button } from './Button' 2 | export type { ButtonProps } from './Button' 3 | -------------------------------------------------------------------------------- /docs/public/screenshots/assets-detail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wzc520pyfm/react-devtools-plus/HEAD/docs/public/screenshots/assets-detail.png -------------------------------------------------------------------------------- /docs/public/screenshots/scan-detail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wzc520pyfm/react-devtools-plus/HEAD/docs/public/screenshots/scan-detail.png -------------------------------------------------------------------------------- /docs/public/screenshots/component-tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wzc520pyfm/react-devtools-plus/HEAD/docs/public/screenshots/component-tree.png -------------------------------------------------------------------------------- /docs/public/screenshots/timeline-detail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wzc520pyfm/react-devtools-plus/HEAD/docs/public/screenshots/timeline-detail.png -------------------------------------------------------------------------------- /docs/public/screenshots/component-tree-detail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wzc520pyfm/react-devtools-plus/HEAD/docs/public/screenshots/component-tree-detail.png -------------------------------------------------------------------------------- /packages/playground/react/src/pages/Theme.tsx: -------------------------------------------------------------------------------- 1 | import { ThemeDemo } from '../ThemeDemo' 2 | 3 | export default function Theme() { 4 | return 5 | } 6 | -------------------------------------------------------------------------------- /packages/playground/react-webpack/src/pages/Theme.jsx: -------------------------------------------------------------------------------- 1 | import { ThemeDemo } from '../ThemeDemo' 2 | 3 | export default function Theme() { 4 | return 5 | } 6 | -------------------------------------------------------------------------------- /packages/playground/react17-webpack4/src/pages/Theme.jsx: -------------------------------------------------------------------------------- 1 | import { ThemeDemo } from '../ThemeDemo' 2 | 3 | export default function Theme() { 4 | return 5 | } 6 | -------------------------------------------------------------------------------- /packages/react-devtools/src/config/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Configuration module exports 3 | * 配置模块导出 4 | */ 5 | 6 | export * from './normalize' 7 | export * from './types' 8 | -------------------------------------------------------------------------------- /packages/react-devtools/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Utilities module exports 3 | * 工具模块导出 4 | */ 5 | 6 | export * from './babel-transform' 7 | export * from './paths' 8 | -------------------------------------------------------------------------------- /packages/react-devtools/src/shims.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'virtual:react-devtools-options' { 2 | const options: { 3 | base: string 4 | } 5 | export default options 6 | } 7 | -------------------------------------------------------------------------------- /packages/react-devtools-kit/src/messaging/types/channel.ts: -------------------------------------------------------------------------------- 1 | export interface MergeableChannelOptions { 2 | post: (data: any) => void 3 | on: (handler: (data: any) => void) => void 4 | } 5 | -------------------------------------------------------------------------------- /packages/playground/react17-scss/src/pages/Theme.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { ThemeDemo } from '../ThemeDemo' 3 | 4 | export default function Theme() { 5 | return 6 | } 7 | -------------------------------------------------------------------------------- /packages/react-devtools/src/overlay.ts: -------------------------------------------------------------------------------- 1 | // This file is a placeholder that will be replaced by the overlay package build output 2 | // The actual overlay code is in packages/react-devtools-overlay 3 | -------------------------------------------------------------------------------- /packages/react-devtools-client/src/components/graph/index.ts: -------------------------------------------------------------------------------- 1 | export { GraphDrawer } from './GraphDrawer' 2 | export { GraphFileType } from './GraphFileType' 3 | export { GraphNavbar } from './GraphNavbar' 4 | -------------------------------------------------------------------------------- /packages/react-devtools-core/src/plugin/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Plugin system exports 3 | * 插件系统导出 4 | */ 5 | 6 | export type { DevToolsPlugin, PluginContext } from '../types' 7 | export * from './manager' 8 | -------------------------------------------------------------------------------- /packages/react-devtools-kit/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './core' 2 | export * from './messaging' 3 | export { setIframeServerContext } from './messaging/presets/iframe/context' 4 | export * from './types' 5 | -------------------------------------------------------------------------------- /packages/react-devtools/src/integrations/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Integration module exports 3 | * 构建工具集成模块导出 4 | */ 5 | 6 | export * from './umi' 7 | export * from './vite' 8 | export * from './webpack' 9 | -------------------------------------------------------------------------------- /packages/playground/umi/.gitignore: -------------------------------------------------------------------------------- 1 | # umi 2 | .umi 3 | .umi-production 4 | .umi-test 5 | dist 6 | 7 | # dependencies 8 | node_modules 9 | 10 | # misc 11 | .DS_Store 12 | *.log 13 | 14 | # IDE 15 | .idea 16 | .vscode 17 | -------------------------------------------------------------------------------- /packages/react-devtools-kit/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./dist" 5 | }, 6 | "include": ["src/**/*"], 7 | "exclude": ["node_modules", "dist"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/playground/react/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.json", 3 | "compilerOptions": { 4 | "jsx": "react-jsx", 5 | "types": ["vite/client"] 6 | }, 7 | "include": [ 8 | "src" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /packages/react-devtools-core/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "dist" 5 | }, 6 | "include": ["src/**/*"], 7 | "exclude": ["node_modules", "dist", "examples"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/playground/react19/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.json", 3 | "compilerOptions": { 4 | "jsx": "react-jsx", 5 | "types": ["vite/client"] 6 | }, 7 | "include": [ 8 | "src" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /packages/react-devtools-scan/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "rootDir": "src", 5 | "outDir": "dist" 6 | }, 7 | "include": ["src/**/*"], 8 | "exclude": ["dist", "node_modules"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/react-devtools-ui/src/types.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.module.css' { 2 | const classes: { [key: string]: string } 3 | export default classes 4 | } 5 | 6 | declare module '*.css' { 7 | const content: string 8 | export default content 9 | } 10 | -------------------------------------------------------------------------------- /packages/ui-story/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "jsx": "react-jsx", 5 | "skipLibCheck": true 6 | }, 7 | "include": [ 8 | ".storybook/**/*", 9 | "stories/**/*" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /docs/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "React DevTools Plus Landing", 3 | "description": "A high-performance, aesthetically stunning marketing landing page for React DevTools Plus, featuring dark mode, beam animations, and glassmorphism.", 4 | "requestFramePermissions": [] 5 | } 6 | -------------------------------------------------------------------------------- /uno.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'unocss' 2 | 3 | import config from './packages/react-devtools-client/uno.config' 4 | 5 | export default defineConfig({ 6 | ...config, 7 | configDeps: [ 8 | './packages/react-devtools-client/uno.config.ts', 9 | ], 10 | }) 11 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_size = 2 6 | indent_style = space 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | insert_final_newline = false 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /packages/react-devtools-ui/src/index.ts: -------------------------------------------------------------------------------- 1 | // Export components 2 | // Import base styles 3 | import './styles/base.css' 4 | 5 | export * from './components' 6 | 7 | // Export composables 8 | export * from './composables/useTheme' 9 | 10 | // Export theme 11 | export * from './theme' 12 | -------------------------------------------------------------------------------- /packages/react-devtools/src/middleware/client-server.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Client serving middleware 3 | * 客户端服务中间件 4 | */ 5 | import sirv from 'sirv' 6 | 7 | export function serveClient(servePath: string) { 8 | return sirv(servePath, { 9 | single: true, 10 | dev: true, 11 | }) 12 | } 13 | -------------------------------------------------------------------------------- /packages/playground/my-devtools-play/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App.tsx' 4 | 5 | ReactDOM.createRoot(document.getElementById('root')!).render( 6 | 7 | 8 | , 9 | ) 10 | -------------------------------------------------------------------------------- /packages/react-devtools-ui/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "ESNext", 5 | "moduleResolution": "bundler", 6 | "allowSyntheticDefaultImports": true, 7 | "skipLibCheck": true 8 | }, 9 | "include": ["vite.config.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/react-devtools/src/compat/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Compatibility Layer 3 | * 4 | * - Webpack 4/5 5 | * - webpack-dev-server 3/4+ 6 | * - React 17/18+ 7 | */ 8 | 9 | export * from './react-version' 10 | export * from './webpack-dev-server-version' 11 | export * from './webpack-version' 12 | -------------------------------------------------------------------------------- /packages/react-devtools-ui/src/components/index.ts: -------------------------------------------------------------------------------- 1 | // Export all components 2 | export * from './Badge' 3 | export * from './Button' 4 | export * from './Card' 5 | export * from './Checkbox' 6 | export * from './Input' 7 | export * from './Select' 8 | export * from './Switch' 9 | export * from './Tag' 10 | -------------------------------------------------------------------------------- /packages/react-devtools/src/middleware/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Middleware module exports 3 | * 中间件模块导出 4 | */ 5 | 6 | export * from './assets' 7 | export * from './client-server' 8 | export * from './graph' 9 | export * from './open-in-editor' 10 | export * from './plugin-file' 11 | export * from './plugins' 12 | -------------------------------------------------------------------------------- /packages/shared/tsdown.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsdown' 2 | 3 | export default defineConfig({ 4 | entry: [ 5 | 'src/index.ts', 6 | ], 7 | clean: true, 8 | format: ['esm', 'cjs'], 9 | target: 'node14', 10 | dts: true, 11 | shims: true, 12 | noExternal: ['rfdc'], 13 | }) 14 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | import React from '@vitejs/plugin-react' 2 | import { defineConfig } from 'vitest/config' 3 | 4 | export default defineConfig({ 5 | plugins: [React()], 6 | define: { 7 | __DEV__: true, 8 | __FEATURE_PROD_DEVTOOLS__: true, 9 | }, 10 | test: { 11 | environment: 'jsdom', 12 | globals: true, 13 | }, 14 | }) 15 | -------------------------------------------------------------------------------- /packages/playground/react-webpack/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | React DevTools Webpack Playground 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /packages/shared/src/constants.ts: -------------------------------------------------------------------------------- 1 | export const VIEW_MODE_STORAGE_KEY = '__react-devtools-view-mode__' 2 | export const VITE_PLUGIN_DETECTED_STORAGE_KEY = '__react-devtools-vite-plugin-detected__' 3 | export const VITE_PLUGIN_CLIENT_URL_STORAGE_KEY = '__react-devtools-vite-plugin-client-url__' 4 | export const BROADCAST_CHANNEL_NAME = '__react-devtools-broadcast-channel__' 5 | -------------------------------------------------------------------------------- /packages/react-devtools-client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "jsx": "react-jsx", 5 | "baseUrl": ".", 6 | "rootDir": "./src", 7 | "paths": { 8 | "~/*": ["./src/*"] 9 | }, 10 | "outDir": "./dist" 11 | }, 12 | "include": ["src/**/*"], 13 | "exclude": ["node_modules", "dist"] 14 | } 15 | -------------------------------------------------------------------------------- /packages/ui-story/.storybook/preview.ts: -------------------------------------------------------------------------------- 1 | import type { Preview } from '@storybook/react' 2 | import '@react-devtools-plus/ui/style.css' 3 | 4 | const preview: Preview = { 5 | parameters: { 6 | controls: { 7 | matchers: { 8 | color: /(background|color)$/i, 9 | date: /Date$/i, 10 | }, 11 | }, 12 | }, 13 | } 14 | 15 | export default preview 16 | -------------------------------------------------------------------------------- /packages/react-devtools-client/src/global.css: -------------------------------------------------------------------------------- 1 | :root { 2 | background-color: transparent; 3 | color-scheme: light dark; 4 | } 5 | 6 | html, 7 | body { 8 | width: 100%; 9 | height: 100%; 10 | margin: 0; 11 | background-color: var(--surface-base, #0f172a); 12 | } 13 | 14 | body { 15 | overflow: hidden; 16 | } 17 | 18 | #root { 19 | width: 100%; 20 | height: 100%; 21 | } 22 | -------------------------------------------------------------------------------- /packages/playground/react/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | React DevTools Playground 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /packages/react-devtools-core/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * React DevTools Core 3 | * React DevTools 核心功能 4 | */ 5 | 6 | // Export client 7 | export * from './client' 8 | 9 | // Export events 10 | export * from './events' 11 | 12 | // Export plugin system 13 | export * from './plugin' 14 | 15 | // Export RPC 16 | export * from './rpc' 17 | 18 | // Export types 19 | export type * from './types' 20 | -------------------------------------------------------------------------------- /packages/playground/react19/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | React 19 DevTools Playground 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /packages/react-devtools-overlay/src/composables/usePanelVisible.ts: -------------------------------------------------------------------------------- 1 | import { useState } from 'react' 2 | 3 | export function usePanelVisible() { 4 | const [panelVisible, setPanelVisible] = useState(false) 5 | 6 | const togglePanel = () => { 7 | setPanelVisible(prev => !prev) 8 | } 9 | 10 | return { 11 | panelVisible, 12 | setPanelVisible, 13 | togglePanel, 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/playground/react17-scss/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | 26 | -------------------------------------------------------------------------------- /packages/playground/react17-webpack4/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | 26 | -------------------------------------------------------------------------------- /docs/src/types.ts: -------------------------------------------------------------------------------- 1 | export interface Feature { 2 | title: string 3 | description: string 4 | icon: React.ComponentType<{ className?: string }> 5 | className?: string 6 | gradient?: string 7 | } 8 | 9 | export interface Testimonial { 10 | quote: string 11 | author: string 12 | role: string 13 | avatar?: string 14 | } 15 | 16 | export interface NavLink { 17 | label: string 18 | href: string 19 | } 20 | -------------------------------------------------------------------------------- /packages/playground/react17-scss/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | React DevTools Playground - React 17 + SCSS 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /bump.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'bumpp' 2 | import fg from 'fast-glob' 3 | 4 | export default defineConfig({ 5 | files: fg.sync(['./packages/*/package.json'], { 6 | ignore: [ 7 | // 不需要发布的包 8 | './packages/playground/*/package.json', 9 | ], 10 | }), 11 | // 自动 push commit 和 tag 到远程 12 | push: true, 13 | // tag 格式 14 | tag: true, 15 | // commit 消息格式 16 | commit: 'release: v%s', 17 | }) 18 | -------------------------------------------------------------------------------- /packages/playground/umi/plugin.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * React DevTools Plus - Umi Plugin 3 | * 4 | * This plugin integrates react-devtools-plus with Umi's dev server 5 | */ 6 | import { createUmiPlugin } from 'react-devtools-plus/umi' 7 | 8 | export default createUmiPlugin({ 9 | enabledEnvironments: ['development', 'test'], 10 | scan: { 11 | enabled: true, 12 | showToolbar: false, 13 | animationSpeed: 'fast', 14 | }, 15 | }) 16 | -------------------------------------------------------------------------------- /packages/react-devtools-kit/src/core/index.ts: -------------------------------------------------------------------------------- 1 | export * from './context' 2 | export * from './fiber/details' 3 | export * from './fiber/highlight' 4 | export * from './fiber/props' 5 | export * from './fiber/state' 6 | export * from './fiber/tree' 7 | export * from './fiber/utils' 8 | export * from './hook' 9 | export * from './inspector' 10 | export * from './open-in-editor' 11 | export * from './router' 12 | export * from './timeline' 13 | -------------------------------------------------------------------------------- /packages/playground/react19/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App' 4 | import './style.css' 5 | 6 | // Note: React Scan is now auto-injected via vite.config.ts 7 | // 注意:React Scan 现在通过 vite.config.ts 自动注入 8 | 9 | ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( 10 | 11 | 12 | , 13 | ) 14 | -------------------------------------------------------------------------------- /packages/playground/react17-webpack4/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | React DevTools Playground - React 17 + Webpack 4 + SCSS 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /packages/react-devtools/src/codegen/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Code Generation Module 3 | * 4 | * - React DevTools Hook initialization 5 | * - React globals setup 6 | * - React Scan initialization 7 | * - CSS injection 8 | * - Configuration injection 9 | */ 10 | 11 | export * from './config-injector' 12 | export * from './css-injector' 13 | export * from './devtools-hook' 14 | export * from './react-globals' 15 | export * from './scan-init' 16 | -------------------------------------------------------------------------------- /packages/react-devtools-kit/src/messaging/presets/iframe/context.ts: -------------------------------------------------------------------------------- 1 | let iframeServerContext: HTMLIFrameElement | null = null 2 | 3 | export function setIframeServerContext(iframe: HTMLIFrameElement | null) { 4 | iframeServerContext = iframe 5 | } 6 | 7 | export function getIframeServerContext() { 8 | return iframeServerContext 9 | } 10 | 11 | export const __REACT_DEVTOOLS_KIT_IFRAME_MESSAGING_EVENT_KEY = '__REACT_DEVTOOLS_KIT_IFRAME_MESSAGE__' 12 | -------------------------------------------------------------------------------- /packages/react-devtools-overlay/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "target": "esnext", 5 | "jsx": "react-jsx", 6 | "lib": ["esnext", "dom"], 7 | "module": "esnext", 8 | "moduleResolution": "bundler", 9 | "types": ["vite/client"], 10 | "strict": true, 11 | "outDir": "./dist", 12 | "skipLibCheck": true 13 | }, 14 | "include": ["src/**/*.ts", "src/**/*.tsx"] 15 | } 16 | -------------------------------------------------------------------------------- /packages/playground/my-devtools-play/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | My DevTools Playground 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/playground/react17-webpack4/src/App.jsx: -------------------------------------------------------------------------------- 1 | import { Route, Switch } from 'react-router-dom' 2 | import Layout from './components/Layout' 3 | import Home from './pages/Home' 4 | import Theme from './pages/Theme' 5 | 6 | export default function App() { 7 | return ( 8 | 9 | 10 | 11 | 12 | 13 | 14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /docs/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App' 4 | import './lib/i18n' 5 | import './styles/globals.css' 6 | 7 | const rootElement = document.getElementById('root') 8 | if (!rootElement) { 9 | throw new Error('Could not find root element to mount to') 10 | } 11 | 12 | const root = ReactDOM.createRoot(rootElement) 13 | root.render( 14 | 15 | 16 | , 17 | ) 18 | -------------------------------------------------------------------------------- /packages/react-devtools-kit/tsdown.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsdown' 2 | 3 | export default defineConfig({ 4 | entry: ['src/index.ts'], 5 | clean: true, 6 | format: ['esm', 'cjs'], 7 | // Use es2017 for maximum compatibility with Webpack 4 8 | target: 'es2017', 9 | dts: true, 10 | shims: true, 11 | // Bundle these dependencies to avoid pnpm resolution issues in Webpack 4 12 | noExternal: ['superjson', 'birpc', 'copy-anything', 'is-what'], 13 | }) 14 | -------------------------------------------------------------------------------- /packages/playground/react/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { Route, Routes } from 'react-router-dom' 2 | import Layout from './components/Layout' 3 | import Home from './pages/Home' 4 | import Theme from './pages/Theme' 5 | 6 | export default function App() { 7 | return ( 8 | 9 | }> 10 | } /> 11 | } /> 12 | 13 | 14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /packages/playground/react-webpack/src/App.jsx: -------------------------------------------------------------------------------- 1 | import { Route, Routes } from 'react-router-dom' 2 | import Layout from './components/Layout' 3 | import Home from './pages/Home' 4 | import Theme from './pages/Theme' 5 | 6 | export default function App() { 7 | return ( 8 | 9 | }> 10 | } /> 11 | } /> 12 | 13 | 14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /packages/react-devtools/src/dir.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'node:path' 2 | 3 | /** 4 | * Directory constants 5 | * __dirname is provided by: 6 | * - CJS: Node.js built-in 7 | * - ESM: tsup banner polyfill (see tsup.config.ts) 8 | */ 9 | export const DIR_DIST = __dirname 10 | 11 | // The overlay is in src/overlay relative to package root 12 | // DIR_DIST points to dist/, so we need to go up one level and into src/overlay 13 | export const DIR_OVERLAY = resolve(DIR_DIST, '../src/overlay') 14 | -------------------------------------------------------------------------------- /packages/react-devtools/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "composite": false, 5 | "target": "ES2017", 6 | "rootDir": "src", 7 | "module": "ESNext", 8 | "moduleResolution": "bundler", 9 | "types": [ 10 | "vite/client" 11 | ], 12 | "declaration": true, 13 | "declarationMap": false, 14 | "emitDeclarationOnly": true, 15 | "outDir": "dist" 16 | }, 17 | "include": [ 18 | "src" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /packages/playground/umi/src/app.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Umi runtime configuration 3 | * This file is used to expose React to window for react-devtools-plus overlay 4 | */ 5 | import React from 'react' 6 | import ReactDOM from 'react-dom' 7 | 8 | // Expose React and ReactDOM to window for react-devtools-plus overlay 9 | if (typeof window !== 'undefined') { 10 | ;(window as any).React = React 11 | ;(window as any).ReactDOM = ReactDOM 12 | } 13 | 14 | // Export empty object for umi runtime config 15 | export {} 16 | -------------------------------------------------------------------------------- /packages/react-devtools/src/webpack.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Webpack Plugin Entry 3 | * 4 | * @example 5 | * ```js 6 | * const { reactDevToolsPlus } = require('react-devtools-plus/webpack') 7 | * 8 | * module.exports = { 9 | * plugins: [ 10 | * reactDevToolsPlus(), 11 | * ], 12 | * } 13 | * ``` 14 | */ 15 | 16 | import { webpack } from './unplugin.js' 17 | 18 | export { webpack as reactDevToolsPlus } 19 | export default webpack 20 | export type { ReactDevToolsPluginOptions } from './unplugin.js' 21 | -------------------------------------------------------------------------------- /docs/vite.config.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path' 2 | import react from '@vitejs/plugin-react' 3 | import { defineConfig } from 'vite' 4 | 5 | export default defineConfig({ 6 | server: { 7 | port: 3000, 8 | host: '0.0.0.0', 9 | }, 10 | plugins: [react()], 11 | resolve: { 12 | alias: { 13 | '@': path.resolve(__dirname, './src'), 14 | }, 15 | dedupe: ['react', 'react-dom'], 16 | }, 17 | optimizeDeps: { 18 | include: ['react', 'react-dom', 'react-router-dom'], 19 | }, 20 | }) 21 | -------------------------------------------------------------------------------- /packages/react-devtools/src/vite.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Vite Plugin Entry 3 | * 4 | * @example 5 | * ```ts 6 | * import { reactDevToolsPlus } from 'react-devtools-plus/vite' 7 | * 8 | * export default defineConfig({ 9 | * plugins: [ 10 | * react(), 11 | * reactDevToolsPlus(), 12 | * ], 13 | * }) 14 | * ``` 15 | */ 16 | 17 | import { vite } from './unplugin.js' 18 | 19 | export { vite as reactDevToolsPlus } 20 | export default vite 21 | export type { ReactDevToolsPluginOptions } from './unplugin.js' 22 | -------------------------------------------------------------------------------- /packages/ui-story/.storybook/main.ts: -------------------------------------------------------------------------------- 1 | import type { StorybookConfig } from '@storybook/react-vite' 2 | 3 | const config: StorybookConfig = { 4 | stories: ['../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)'], 5 | addons: [ 6 | '@storybook/addon-links', 7 | '@storybook/addon-essentials', 8 | '@storybook/addon-interactions', 9 | ], 10 | framework: { 11 | name: '@storybook/react-vite', 12 | options: {}, 13 | }, 14 | docs: { 15 | autodocs: 'tag', 16 | }, 17 | } 18 | 19 | export default config 20 | -------------------------------------------------------------------------------- /packages/playground/react17-scss/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.json", 3 | "compilerOptions": { 4 | "target": "ES2017", 5 | "jsx": "react", 6 | "jsxFactory": "React.createElement", 7 | "jsxFragmentFactory": "React.Fragment", 8 | "lib": ["ES2017", "DOM", "DOM.Iterable"], 9 | "baseUrl": ".", 10 | "paths": { 11 | "@/*": ["./src/*"] 12 | }, 13 | "allowSyntheticDefaultImports": true, 14 | "skipLibCheck": true 15 | }, 16 | "include": ["src"], 17 | "exclude": ["node_modules", "dist"] 18 | } 19 | -------------------------------------------------------------------------------- /packages/react-devtools-client/src/types/plugin.ts: -------------------------------------------------------------------------------- 1 | export interface UserPluginView { 2 | title: string 3 | icon: string 4 | src: string 5 | } 6 | 7 | export interface UserPlugin { 8 | name: string 9 | view?: UserPluginView 10 | } 11 | 12 | export interface DevToolsPluginContext { 13 | tree: any 14 | selectedNodeId: string | null 15 | theme: any 16 | // We can add more RPC-like helpers here later if needed 17 | } 18 | 19 | export interface LoadedPlugin extends UserPlugin { 20 | component?: React.ComponentType 21 | } 22 | -------------------------------------------------------------------------------- /packages/playground/my-devtools-play/vite.config.ts: -------------------------------------------------------------------------------- 1 | import react from '@vitejs/plugin-react' 2 | import MyDevTools from 'my-devtools' 3 | import { defineConfig } from 'vite' 4 | 5 | // https://vitejs.dev/config/ 6 | export default defineConfig({ 7 | plugins: [ 8 | // User just uses MyDevTools, and gets the "ContextInspector" plugin for free! 9 | MyDevTools.vite({ 10 | theme: { 11 | mode: 'dark', // auto or light or dark 12 | primaryColor: 'orange', // Custom primary color 13 | }, 14 | }), 15 | react(), 16 | ], 17 | }) 18 | -------------------------------------------------------------------------------- /packages/playground/umi/typings.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.less' { 2 | const classes: { readonly [key: string]: string } 3 | export default classes 4 | } 5 | 6 | declare module '*.css' { 7 | const classes: { readonly [key: string]: string } 8 | export default classes 9 | } 10 | 11 | declare module '*.svg' { 12 | const content: string 13 | export default content 14 | } 15 | 16 | declare module '*.png' { 17 | const content: string 18 | export default content 19 | } 20 | 21 | declare module '*.jpg' { 22 | const content: string 23 | export default content 24 | } 25 | -------------------------------------------------------------------------------- /packages/playground/umi/src/global.less: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | html, 6 | body { 7 | margin: 0; 8 | padding: 0; 9 | font-family: 10 | -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 11 | 'Helvetica Neue', sans-serif; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | } 15 | 16 | a { 17 | text-decoration: none; 18 | } 19 | 20 | ul { 21 | list-style: none; 22 | margin: 0; 23 | padding: 0; 24 | } 25 | 26 | button { 27 | font-family: inherit; 28 | } 29 | -------------------------------------------------------------------------------- /packages/react-devtools-client/src/types/messages.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Message types for communication between client iframe and overlay 3 | */ 4 | 5 | export interface InstallComponentTreeHookMessage { 6 | type: '__REACT_DEVTOOLS_INSTALL_COMPONENT_TREE_HOOK__' 7 | } 8 | 9 | export type DevToolsMessage = InstallComponentTreeHookMessage 10 | 11 | /** 12 | * Type guard to check if a message is a valid DevTools message 13 | */ 14 | export function isDevToolsMessage(data: any): data is DevToolsMessage { 15 | return data && typeof data.type === 'string' && data.type.startsWith('__REACT_DEVTOOLS_') 16 | } 17 | -------------------------------------------------------------------------------- /packages/playground/react19/vite.config.ts: -------------------------------------------------------------------------------- 1 | import react from '@vitejs/plugin-react' 2 | import { reactDevToolsPlus } from 'react-devtools-plus/vite' 3 | import { defineConfig } from 'vite' 4 | 5 | export default defineConfig({ 6 | plugins: [ 7 | reactDevToolsPlus({ 8 | enabledEnvironments: ['development', 'test'], 9 | // Enable React Scan auto-injection 10 | scan: { 11 | enabled: true, // Enable injection, but controlled by showToolbar/DevTools 12 | showToolbar: false, 13 | animationSpeed: 'fast', 14 | }, 15 | }), 16 | react(), 17 | ], 18 | }) 19 | -------------------------------------------------------------------------------- /packages/react-devtools-client/src/components/assets/ReactLogo.tsx: -------------------------------------------------------------------------------- 1 | export default function ReactLogo({ className }: { className?: string }) { 2 | return ( 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /packages/react-devtools-scan/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup' 2 | 3 | export default defineConfig({ 4 | entry: { 5 | index: 'src/index.ts', 6 | }, 7 | format: ['esm', 'cjs'], 8 | // Use es2017 for maximum compatibility with Webpack 4 9 | // Node 14+ and modern browsers support ES2017 10 | target: 'es2017', 11 | dts: { 12 | resolve: true, 13 | }, 14 | outDir: 'dist', 15 | clean: true, 16 | shims: true, 17 | splitting: false, 18 | sourcemap: true, 19 | external: ['react', 'react-dom'], 20 | noExternal: ['react-scan'], 21 | skipNodeModulesBundle: false, 22 | }) 23 | -------------------------------------------------------------------------------- /packages/playground/my-devtools-play/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-devtools-play", 3 | "type": "module", 4 | "version": "0.0.0", 5 | "private": true, 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc && vite build", 9 | "preview": "vite preview" 10 | }, 11 | "dependencies": { 12 | "my-devtools": "workspace:*", 13 | "react": "^18.3.1", 14 | "react-dom": "^18.3.1" 15 | }, 16 | "devDependencies": { 17 | "@types/react": "^18.3.3", 18 | "@types/react-dom": "^18.3.0", 19 | "@vitejs/plugin-react": "^4.3.1", 20 | "typescript": "^5.4.5", 21 | "vite": "^5.2.11" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/playground/umi/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-devtools-plus/playground-umi", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "umi dev", 7 | "build": "umi build", 8 | "setup": "umi setup", 9 | "start": "npm run dev" 10 | }, 11 | "dependencies": { 12 | "@react-devtools-plus/ui": "workspace:*", 13 | "react": "^18.3.1", 14 | "react-dom": "^18.3.1", 15 | "umi": "^4.6.5" 16 | }, 17 | "devDependencies": { 18 | "@types/react": "^18.2.72", 19 | "@types/react-dom": "^18.2.23", 20 | "react-devtools-plus": "workspace:*", 21 | "typescript": "^5.9.3" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/playground/react17-webpack4/src/main.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import { BrowserRouter } from 'react-router-dom' 4 | import App from './App' 5 | import './style.scss' 6 | 7 | // Note: React Scan is now auto-injected via webpack.config.js 8 | // 注意:React Scan 现在通过 webpack.config.js 自动注入 9 | 10 | // React 17 uses ReactDOM.render (not createRoot which is React 18+) 11 | // eslint-disable-next-line react-dom/no-render 12 | ReactDOM.render( 13 | 14 | 15 | 16 | 17 | , 18 | document.getElementById('root'), 19 | ) 20 | -------------------------------------------------------------------------------- /packages/playground/umi/.umirc.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'umi' 2 | 3 | export default defineConfig({ 4 | // 路由配置 5 | routes: [ 6 | { path: '/', component: 'index' }, 7 | { path: '/about', component: 'about' }, 8 | { path: '/theme', component: 'theme' }, 9 | { path: '/counter', component: 'counter' }, 10 | ], 11 | 12 | // umi 会自动加载项目根目录下的 plugin.ts 文件 13 | // 无需在 plugins 中手动配置 14 | 15 | // 开发服务器配置 16 | devtool: 'source-map', 17 | 18 | // 禁用 MFSU 以便更好地测试 react-devtools-plus 19 | // 你可以根据需要启用 20 | mfsu: false, 21 | 22 | // 其他 umi 配置 23 | npmClient: 'pnpm', 24 | title: 'React DevTools Plus - Umi Playground', 25 | }) 26 | -------------------------------------------------------------------------------- /packages/playground/my-devtools-play/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "jsx": "react-jsx", 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "useDefineForClassFields": true, 7 | "module": "ESNext", 8 | "moduleResolution": "bundler", 9 | "resolveJsonModule": true, 10 | "types": ["vite/client"], 11 | "allowImportingTsExtensions": true, 12 | "strict": true, 13 | "noFallthroughCasesInSwitch": true, 14 | "noUnusedLocals": true, 15 | "noUnusedParameters": true, 16 | "noEmit": true, 17 | "isolatedModules": true, 18 | "skipLibCheck": true 19 | }, 20 | "include": ["src"] 21 | } 22 | -------------------------------------------------------------------------------- /packages/playground/react17-scss/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Route, Switch } from 'react-router-dom' 3 | import Layout from './components/Layout' 4 | import Home from './pages/Home' 5 | import Theme from './pages/Theme' 6 | 7 | export default function App() { 8 | return ( 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | ) 24 | } 25 | -------------------------------------------------------------------------------- /packages/react-devtools/src/umi.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Umi Plugin Entry 3 | * 4 | * @example 5 | * ```ts 6 | * // plugin.ts (in your Umi project) 7 | * import { createUmiPlugin } from 'react-devtools-plus/umi' 8 | * 9 | * export default createUmiPlugin({ 10 | * scan: { enabled: true }, 11 | * }) 12 | * ``` 13 | * 14 | * Then add to .umirc.ts: 15 | * ```ts 16 | * export default defineConfig({ 17 | * plugins: ['./plugin.ts'], 18 | * }) 19 | * ``` 20 | */ 21 | 22 | import { createUmiPlugin } from './integrations/umi.js' 23 | 24 | export { createUmiPlugin } 25 | export default createUmiPlugin 26 | export type { ReactDevToolsPluginOptions } from './config/types.js' 27 | -------------------------------------------------------------------------------- /packages/playground/react19/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-devtools-plus/playground-react19", 3 | "type": "module", 4 | "version": "0.0.0", 5 | "private": true, 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "NODE_ENV=test vite build --mode test", 9 | "preview": "NODE_ENV=test vite preview --mode test" 10 | }, 11 | "dependencies": { 12 | "react": "^19.0.0", 13 | "react-dom": "^19.0.0" 14 | }, 15 | "devDependencies": { 16 | "@types/react": "^19.0.0", 17 | "@types/react-dom": "^19.0.0", 18 | "@vitejs/plugin-react": "^4.3.2", 19 | "react-devtools-plus": "workspace:*", 20 | "typescript": "^5.9.3", 21 | "vite": "^7.1.10" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /docs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "jsx": "react-jsx", 5 | "lib": ["ES2022", "DOM", "DOM.Iterable"], 6 | "moduleDetection": "force", 7 | "useDefineForClassFields": false, 8 | "experimentalDecorators": true, 9 | "baseUrl": ".", 10 | "module": "ESNext", 11 | "moduleResolution": "bundler", 12 | "paths": { 13 | "@/*": ["./src/*"] 14 | }, 15 | "types": ["node"], 16 | "allowImportingTsExtensions": true, 17 | "allowJs": true, 18 | "strict": true, 19 | "noEmit": true, 20 | "isolatedModules": true, 21 | "skipLibCheck": true 22 | }, 23 | "include": ["src/**/*", "*.config.ts"], 24 | "exclude": ["node_modules"] 25 | } 26 | -------------------------------------------------------------------------------- /packages/playground/my-devtools/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-devtools", 3 | "version": "0.0.1", 4 | "private": true, 5 | "exports": { 6 | ".": { 7 | "types": "./dist/index.d.ts", 8 | "import": "./dist/index.mjs", 9 | "require": "./dist/index.js" 10 | } 11 | }, 12 | "main": "./dist/index.js", 13 | "module": "./dist/index.mjs", 14 | "types": "./dist/index.d.ts", 15 | "scripts": { 16 | "build": "tsup", 17 | "dev": "tsup --watch" 18 | }, 19 | "dependencies": { 20 | "react-devtools-plus": "workspace:*" 21 | }, 22 | "devDependencies": { 23 | "@types/node": "^20.12.7", 24 | "react": "^18.3.1", 25 | "tsup": "^8.0.2", 26 | "typescript": "^5.4.5" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | React DevTools Plus 7 | 8 | 9 | 10 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /packages/playground/react-webpack/src/main.jsx: -------------------------------------------------------------------------------- 1 | import { ThemeProvider } from '@react-devtools-plus/ui' 2 | import React from 'react' 3 | import ReactDOM from 'react-dom/client' 4 | import { BrowserRouter } from 'react-router-dom' 5 | import App from './App' 6 | import '@react-devtools-plus/ui/style.css' 7 | import './style.css' 8 | 9 | // Note: React Scan is now auto-injected via webpack.config.js 10 | // 注意:React Scan 现在通过 webpack.config.js 自动注入 11 | 12 | ReactDOM.createRoot(document.getElementById('root')).render( 13 | 14 | 15 | 16 | 17 | 18 | 19 | , 20 | ) 21 | -------------------------------------------------------------------------------- /packages/playground/react/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { ThemeProvider } from '@react-devtools-plus/ui' 2 | import React from 'react' 3 | import ReactDOM from 'react-dom/client' 4 | import { BrowserRouter } from 'react-router-dom' 5 | import App from './App' 6 | import '@react-devtools-plus/ui/style.css' 7 | import './style.css' 8 | 9 | // Note: React Scan is now auto-injected via vite.config.ts 10 | // 注意:React Scan 现在通过 vite.config.ts 自动注入 11 | 12 | ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( 13 | 14 | 15 | 16 | 17 | 18 | 19 | , 20 | ) 21 | -------------------------------------------------------------------------------- /packages/playground/umi/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "jsx": "react-jsx", 5 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 6 | "baseUrl": ".", 7 | "module": "ESNext", 8 | "moduleResolution": "bundler", 9 | "paths": { 10 | "@/*": ["./*"] 11 | }, 12 | "resolveJsonModule": true, 13 | "strict": true, 14 | "noEmit": true, 15 | "esModuleInterop": true, 16 | "forceConsistentCasingInFileNames": true, 17 | "isolatedModules": true, 18 | "skipLibCheck": true 19 | }, 20 | "include": [ 21 | "**/*.ts", 22 | "**/*.tsx", 23 | ".umirc.ts" 24 | ], 25 | "exclude": [ 26 | "node_modules", 27 | "dist", 28 | ".umi", 29 | ".umi-production" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /packages/react-devtools-client/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'node:path' 2 | import react from '@vitejs/plugin-react' 3 | import UnoCSS from 'unocss/vite' 4 | import { defineConfig } from 'vite' 5 | 6 | export default defineConfig({ 7 | plugins: [ 8 | react(), 9 | UnoCSS(), 10 | ], 11 | resolve: { 12 | alias: { 13 | '~': resolve(__dirname, './src'), 14 | '@react-devtools-plus/kit': resolve(__dirname, '../react-devtools-kit/src/index.ts'), 15 | }, 16 | }, 17 | build: { 18 | target: 'esnext', 19 | minify: true, 20 | emptyOutDir: true, 21 | outDir: 'dist', 22 | rollupOptions: { 23 | input: { 24 | main: resolve(__dirname, 'index.html'), 25 | }, 26 | }, 27 | }, 28 | base: './', 29 | }) 30 | -------------------------------------------------------------------------------- /packages/react-devtools-core/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup' 2 | 3 | export default defineConfig({ 4 | entry: { 5 | 'index': 'src/index.ts', 6 | 'rpc/index': 'src/rpc/index.ts', 7 | 'client/index': 'src/client/index.ts', 8 | 'plugin/index': 'src/plugin/index.ts', 9 | }, 10 | format: ['esm', 'cjs'], 11 | // Use es2017 for maximum compatibility with Webpack 4 12 | target: 'es2017', 13 | dts: { 14 | resolve: true, 15 | }, 16 | outDir: 'dist', 17 | shims: true, 18 | clean: true, 19 | splitting: false, 20 | sourcemap: true, 21 | // Bundle these dependencies to avoid pnpm resolution issues in Webpack 4 22 | noExternal: ['superjson', 'birpc', 'copy-anything', 'is-what'], 23 | skipNodeModulesBundle: false, 24 | }) 25 | -------------------------------------------------------------------------------- /packages/playground/my-devtools/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "jsx": "react-jsx", 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "useDefineForClassFields": true, 7 | "baseUrl": ".", 8 | "module": "ESNext", 9 | "moduleResolution": "bundler", 10 | "paths": { 11 | "react-devtools-plus": ["../../react-devtools/src/index.ts"] 12 | }, 13 | "resolveJsonModule": true, 14 | "types": ["node"], 15 | "allowImportingTsExtensions": true, 16 | "strict": true, 17 | "noFallthroughCasesInSwitch": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noEmit": true, 21 | "isolatedModules": true, 22 | "skipLibCheck": true 23 | }, 24 | "include": ["src"] 25 | } 26 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - packages/* 3 | - docs 4 | - packages/playground/** 5 | 6 | catalog: 7 | '@iconify/json': ^2.2.395 8 | '@types/node': ^24.7.2 9 | '@types/react': ^18.2.72 10 | '@types/react-dom': ^18.2.23 11 | '@unocss/reset': ^66.5.4 12 | '@vitejs/plugin-react': ^4.3.2 13 | birpc: ^0.2.19 14 | colord: ^2.9.3 15 | mitt: ^3.0.1 16 | pathe: ^2.0.3 17 | perfect-debounce: ^2.0.0 18 | react: ^18.3.1 19 | react-dom: ^18.3.1 20 | sass-embedded: ^1.93.2 21 | serve: ^14.2.5 22 | shiki: ^3.13.0 23 | tsdown: ^0.15.7 24 | tsup: ^8.5.1 25 | typescript: ^5.9.3 26 | unocss: ^66.5.4 27 | unplugin-auto-import: ^20.2.0 28 | vite: ^7.1.10 29 | vite-hot-client: ^2.1.0 30 | vite-plugin-dts: ^4.5.4 31 | vite-plugin-inspect: ^11.3.3 32 | -------------------------------------------------------------------------------- /packages/playground/react17-webpack4/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.json", 3 | "compilerOptions": { 4 | "target": "ES2017", 5 | "jsx": "react", 6 | "jsxFactory": "React.createElement", 7 | "jsxFragmentFactory": "React.Fragment", 8 | "lib": ["ES2017", "DOM", "DOM.Iterable"], 9 | "baseUrl": ".", 10 | "module": "ESNext", 11 | "moduleResolution": "node", 12 | "paths": { 13 | "@/*": ["./src/*"] 14 | }, 15 | "resolveJsonModule": true, 16 | "allowJs": true, 17 | "noEmit": true, 18 | "allowSyntheticDefaultImports": true, 19 | "forceConsistentCasingInFileNames": true, 20 | "isolatedModules": true, 21 | "skipLibCheck": true 22 | }, 23 | "include": ["src"], 24 | "exclude": ["node_modules", "dist"] 25 | } 26 | -------------------------------------------------------------------------------- /packages/playground/react17-scss/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { ThemeProvider } from '@react-devtools-plus/ui' 2 | import React from 'react' 3 | import { createRoot } from 'react-dom/client' 4 | import { BrowserRouter } from 'react-router-dom' 5 | import App from './App' 6 | import '@react-devtools-plus/ui/style.css' 7 | import './style.scss' 8 | 9 | // Note: React Scan is now auto-injected via vite.config.ts 10 | // 注意:React Scan 现在通过 vite.config.ts 自动注入 11 | 12 | // React 17 uses ReactDOM.render instead of createRoot 13 | createRoot(document.getElementById('root')).render( 14 | 15 | 16 | 17 | 18 | 19 | 20 | , 21 | ) 22 | -------------------------------------------------------------------------------- /packages/playground/react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-devtools-plus/playground-react", 3 | "type": "module", 4 | "version": "0.0.0", 5 | "private": true, 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "NODE_ENV=test vite build --mode test", 9 | "preview": "NODE_ENV=test vite preview --mode test" 10 | }, 11 | "dependencies": { 12 | "@react-devtools-plus/ui": "workspace:*", 13 | "@types/react-router-dom": "^5.3.3", 14 | "react": "^18.3.1", 15 | "react-dom": "^18.3.1", 16 | "react-router-dom": "^6.26.0" 17 | }, 18 | "devDependencies": { 19 | "@types/react": "^18.2.72", 20 | "@types/react-dom": "^18.2.23", 21 | "@vitejs/plugin-react": "^4.3.2", 22 | "react-devtools-plus": "workspace:*", 23 | "typescript": "^5.9.3", 24 | "vite": "^7.1.10" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-devtools-plus-landing", 3 | "type": "module", 4 | "version": "0.0.0", 5 | "private": true, 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview" 10 | }, 11 | "dependencies": { 12 | "@iconify/react": "^6.0.2", 13 | "i18next": "^23.10.1", 14 | "lucide-react": "^0.556.0", 15 | "react": "^19.2.1", 16 | "react-dom": "^19.2.1", 17 | "react-i18next": "^14.1.3", 18 | "react-router-dom": "^7.0.0", 19 | "shiki": "^3.19.0" 20 | }, 21 | "devDependencies": { 22 | "@types/node": "^22.14.0", 23 | "@vitejs/plugin-react": "^5.0.0", 24 | "autoprefixer": "^10.4.20", 25 | "postcss": "^8.5.3", 26 | "tailwindcss": "^3.4.17", 27 | "typescript": "~5.8.2", 28 | "vite": "^6.2.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/playground/react17-scss/vite.config.ts: -------------------------------------------------------------------------------- 1 | import react from '@vitejs/plugin-react' 2 | import ReactDevTools from 'react-devtools-plus' 3 | import { defineConfig } from 'vite' 4 | 5 | export default defineConfig({ 6 | plugins: [ 7 | ReactDevTools.vite({ 8 | enabledEnvironments: ['development', 'test'], 9 | // Enable React Scan auto-injection 10 | scan: { 11 | enabled: true, // Enable injection, but controlled by showToolbar/DevTools 12 | showToolbar: false, 13 | animationSpeed: 'fast', 14 | }, 15 | }), 16 | react(), 17 | ], 18 | css: { 19 | preprocessorOptions: { 20 | scss: { 21 | // Enable modern SCSS API for better compatibility 22 | api: 'modern-compiler', 23 | }, 24 | }, 25 | }, 26 | build: { 27 | target: 'es2017', 28 | }, 29 | }) 30 | -------------------------------------------------------------------------------- /packages/playground/my-devtools/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { cpSync, existsSync, mkdirSync } from 'node:fs' 2 | import { resolve } from 'node:path' 3 | import { defineConfig } from 'tsup' 4 | 5 | export default defineConfig({ 6 | entry: ['src/index.ts'], 7 | format: ['esm', 'cjs'], 8 | dts: true, 9 | clean: true, 10 | external: ['react-devtools-plus', 'react'], 11 | shims: true, // Inject shims for __dirname, import.meta.url, etc. 12 | onSuccess: async () => { 13 | // Copy plugin source files to dist so they can be loaded by the DevTools server 14 | const srcPlugins = resolve(__dirname, 'src/plugins') 15 | const distPlugins = resolve(__dirname, 'dist/plugins') 16 | 17 | if (!existsSync(distPlugins)) { 18 | mkdirSync(distPlugins, { recursive: true }) 19 | } 20 | 21 | cpSync(srcPlugins, distPlugins, { recursive: true }) 22 | }, 23 | }) 24 | -------------------------------------------------------------------------------- /packages/shared/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-devtools-plus/shared", 3 | "type": "module", 4 | "version": "0.4.0", 5 | "author": "wzc520pyfm", 6 | "license": "MIT", 7 | "repository": { 8 | "directory": "packages/shared", 9 | "type": "git", 10 | "url": "git+https://github.com/vuejs/devtools.git" 11 | }, 12 | "exports": { 13 | ".": { 14 | "import": "./dist/index.js", 15 | "require": "./dist/index.cjs" 16 | } 17 | }, 18 | "main": "./dist/index.cjs", 19 | "module": "./dist/index.js", 20 | "files": [ 21 | "dist" 22 | ], 23 | "scripts": { 24 | "build": "tsdown", 25 | "prepare:type": "tsdown --dts-only", 26 | "stub": "tsdown --watch --onSuccess 'tsdown --dts-only'" 27 | }, 28 | "dependencies": { 29 | "rfdc": "^1.4.1" 30 | }, 31 | "devDependencies": { 32 | "@types/node": "catalog:" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/react-devtools-kit/src/messaging/presets/index.ts: -------------------------------------------------------------------------------- 1 | import { MergeableChannelOptions } from '../types/channel' 2 | import { createBroadcastClientChannel } from './broadcast/client.js' 3 | import { createBroadcastServerChannel } from './broadcast/server.js' 4 | import { createIframeClientChannel } from './iframe/client.js' 5 | import { createIframeServerChannel } from './iframe/server.js' 6 | 7 | export type Presets = 'iframe' | 'broadcast' 8 | 9 | export function getChannel(preset: Presets, host: 'client' | 'server' = 'client'): MergeableChannelOptions { 10 | const channels = { 11 | iframe: { 12 | client: createIframeClientChannel, 13 | server: createIframeServerChannel, 14 | }, 15 | broadcast: { 16 | client: createBroadcastClientChannel, 17 | server: createBroadcastServerChannel, 18 | }, 19 | }[preset] 20 | return channels[host]() 21 | } 22 | -------------------------------------------------------------------------------- /packages/playground/react17-webpack4/src/components/Layout.jsx: -------------------------------------------------------------------------------- 1 | import { Link, useLocation } from 'react-router-dom' 2 | 3 | export default function Layout({ children }) { 4 | const location = useLocation() 5 | 6 | const isActive = (path) => { 7 | return location.pathname === path ? 'active' : '' 8 | } 9 | 10 | return ( 11 |
12 |
13 |

React DevTools Playground

14 |

React 17 + SCSS + Webpack 4 + Node 14+ Compatibility Test

15 |
16 | 24 |
{children}
25 |
26 | ) 27 | } 28 | -------------------------------------------------------------------------------- /packages/react-devtools-ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2017", 4 | "jsx": "react-jsx", 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "useDefineForClassFields": true, 7 | 8 | /* Paths */ 9 | "baseUrl": ".", 10 | "module": "ESNext", 11 | 12 | /* Bundler mode */ 13 | "moduleResolution": "bundler", 14 | "paths": { 15 | "@/*": ["./src/*"] 16 | }, 17 | "resolveJsonModule": true, 18 | "allowImportingTsExtensions": true, 19 | 20 | /* Linting */ 21 | "strict": true, 22 | "noFallthroughCasesInSwitch": true, 23 | "noUnusedLocals": true, 24 | "noUnusedParameters": true, 25 | "declaration": true, 26 | "declarationMap": true, 27 | "noEmit": true, 28 | "isolatedModules": true, 29 | "skipLibCheck": true 30 | }, 31 | "references": [{ "path": "./tsconfig.node.json" }], 32 | "include": ["src"] 33 | } 34 | -------------------------------------------------------------------------------- /packages/playground/my-devtools-play/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react' 2 | 3 | function App() { 4 | const [count, setCount] = useState(0) 5 | 6 | return ( 7 |
8 |

My DevTools Playground

9 |
10 | 15 |

16 | Press 17 | {' '} 18 | Option+Shift+D 19 | {' '} 20 | to open DevTools. 21 |

22 |

23 | You should see the 24 | {' '} 25 | "Inspector" 26 | {' '} 27 | tab which comes pre-installed with MyDevTools! 28 |

29 |
30 |
31 | ) 32 | } 33 | 34 | export default App 35 | -------------------------------------------------------------------------------- /packages/playground/react17-scss/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-devtools-plus/playground-react17-scss", 3 | "type": "module", 4 | "version": "0.0.0", 5 | "private": true, 6 | "engines": { 7 | "node": ">=14.0.0" 8 | }, 9 | "scripts": { 10 | "dev": "vite", 11 | "build": "NODE_ENV=test vite build --mode test", 12 | "preview": "NODE_ENV=test vite preview --mode test" 13 | }, 14 | "dependencies": { 15 | "@react-devtools-plus/ui": "workspace:*", 16 | "@types/react-router-dom": "^5.3.3", 17 | "react": "^17.0.2", 18 | "react-dom": "^17.0.2", 19 | "react-router-dom": "^5.3.4" 20 | }, 21 | "devDependencies": { 22 | "@types/react": "^17.0.75", 23 | "@types/react-dom": "^17.0.25", 24 | "@vitejs/plugin-react": "^4.3.2", 25 | "react-devtools-plus": "workspace:*", 26 | "sass": "^1.83.4", 27 | "typescript": "^5.9.3", 28 | "vite": "^7.1.10" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/shared/src/env.ts: -------------------------------------------------------------------------------- 1 | export const isBrowser = typeof navigator !== 'undefined' 2 | export const target = (typeof window !== 'undefined' 3 | ? window 4 | : typeof globalThis !== 'undefined' 5 | ? globalThis 6 | // eslint-disable-next-line no-restricted-globals 7 | : typeof global !== 'undefined' 8 | // eslint-disable-next-line no-restricted-globals 9 | ? global 10 | : {}) as typeof globalThis 11 | 12 | export const isInChromePanel = typeof target.chrome !== 'undefined' && !!target.chrome.devtools 13 | export const isInIframe = isBrowser && target.self !== target.top 14 | export const isInElectron = typeof navigator !== 'undefined' && navigator.userAgent?.toLowerCase().includes('electron') 15 | // @ts-expect-error skip type check 16 | export const isNuxtApp = typeof window !== 'undefined' && !!window.__NUXT__ 17 | export const isInSeparateWindow = !isInIframe && !isInChromePanel && !isInElectron 18 | -------------------------------------------------------------------------------- /docs/src/pages/index.ts: -------------------------------------------------------------------------------- 1 | export { Community } from './Community' 2 | export { Assets } from './docs/Assets' 3 | export { ComponentTree } from './docs/ComponentTree' 4 | 5 | export { Configuration } from './docs/Configuration' 6 | export { Contributing } from './docs/Contributing' 7 | export { FAQ } from './docs/FAQ' 8 | export { Installation } from './docs/Installation' 9 | // Doc Pages 10 | export { Introduction } from './docs/Introduction' 11 | export { ModuleGraph } from './docs/ModuleGraph' 12 | export { OpenInEditor } from './docs/OpenInEditor' 13 | export { QuickStart } from './docs/QuickStart' 14 | export { Scan } from './docs/Scan' 15 | export { Timeline } from './docs/Timeline' 16 | export { Troubleshooting } from './docs/Troubleshooting' 17 | export { ViteSetup } from './docs/ViteSetup' 18 | export { WebpackSetup } from './docs/WebpackSetup' 19 | // Main Pages 20 | export { Features } from './Features' 21 | export { Integration } from './Integration' 22 | -------------------------------------------------------------------------------- /packages/react-devtools-kit/src/messaging/presets/broadcast/client.ts: -------------------------------------------------------------------------------- 1 | import { isBrowser } from '@react-devtools-plus/shared' 2 | import SuperJSON from 'superjson' 3 | import { MergeableChannelOptions } from '../../types/channel' 4 | 5 | const __REACT_DEVTOOLS_KIT_BROADCAST_MESSAGING_EVENT_KEY = '__REACT_DEVTOOLS_KIT_BROADCAST_MESSAGE__' 6 | 7 | export function createBroadcastClientChannel(): MergeableChannelOptions { 8 | if (!isBrowser) { 9 | return { 10 | post: () => {}, 11 | on: () => {}, 12 | } 13 | } 14 | 15 | const channel = new BroadcastChannel(__REACT_DEVTOOLS_KIT_BROADCAST_MESSAGING_EVENT_KEY) 16 | 17 | return { 18 | post: data => channel.postMessage(SuperJSON.stringify(data)), 19 | on: handler => channel.addEventListener('message', (event) => { 20 | try { 21 | handler(SuperJSON.parse(event.data)) 22 | } 23 | catch (e) { 24 | // ignore parsing errors 25 | } 26 | }), 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/react-devtools-kit/src/messaging/presets/broadcast/server.ts: -------------------------------------------------------------------------------- 1 | import { isBrowser } from '@react-devtools-plus/shared' 2 | import SuperJSON from 'superjson' 3 | import { MergeableChannelOptions } from '../../types/channel' 4 | 5 | const __REACT_DEVTOOLS_KIT_BROADCAST_MESSAGING_EVENT_KEY = '__REACT_DEVTOOLS_KIT_BROADCAST_MESSAGE__' 6 | 7 | export function createBroadcastServerChannel(): MergeableChannelOptions { 8 | if (!isBrowser) { 9 | return { 10 | post: () => {}, 11 | on: () => {}, 12 | } 13 | } 14 | 15 | const channel = new BroadcastChannel(__REACT_DEVTOOLS_KIT_BROADCAST_MESSAGING_EVENT_KEY) 16 | 17 | return { 18 | post: data => channel.postMessage(SuperJSON.stringify(data)), 19 | on: handler => channel.addEventListener('message', (event) => { 20 | try { 21 | handler(SuperJSON.parse(event.data)) 22 | } 23 | catch (e) { 24 | // ignore parsing errors 25 | } 26 | }), 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/playground/react-webpack/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-devtools-plus/playground-react-webpack", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "webpack serve --mode development", 7 | "build": "webpack --mode production" 8 | }, 9 | "dependencies": { 10 | "@react-devtools-plus/scan": "workspace:*", 11 | "@react-devtools-plus/ui": "workspace:*", 12 | "react": "^18.3.1", 13 | "react-dom": "^18.3.1", 14 | "react-router-dom": "^6.26.0" 15 | }, 16 | "devDependencies": { 17 | "@babel/core": "^7.28.4", 18 | "@babel/preset-react": "^7.28.4", 19 | "@babel/preset-typescript": "^7.28.4", 20 | "babel-loader": "^9.2.1", 21 | "css-loader": "^7.1.2", 22 | "html-webpack-plugin": "^5.6.3", 23 | "react-devtools-plus": "workspace:*", 24 | "style-loader": "^4.0.0", 25 | "webpack": "^5.97.1", 26 | "webpack-cli": "^5.1.4", 27 | "webpack-dev-server": "^5.1.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/react-devtools-client/src/events.ts: -------------------------------------------------------------------------------- 1 | type EventHandler = (event: T) => void 2 | 3 | class EventEmitter { 4 | private events: Map> = new Map() 5 | 6 | on(type: string, handler: EventHandler) { 7 | if (!this.events.has(type)) { 8 | this.events.set(type, new Set()) 9 | } 10 | this.events.get(type)!.add(handler) 11 | } 12 | 13 | off(type: string, handler: EventHandler) { 14 | const handlers = this.events.get(type) 15 | if (handlers) { 16 | handlers.delete(handler) 17 | } 18 | } 19 | 20 | emit(type: string, event: T) { 21 | const handlers = this.events.get(type) 22 | if (handlers) { 23 | handlers.forEach((handler) => { 24 | try { 25 | handler(event) 26 | } 27 | catch (e) { 28 | console.error('Error in event handler', e) 29 | } 30 | }) 31 | } 32 | } 33 | } 34 | 35 | export const pluginEvents = new EventEmitter() 36 | -------------------------------------------------------------------------------- /packages/playground/react17-scss/src/components/Layout.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link, useLocation } from 'react-router-dom' 3 | 4 | interface LayoutProps { 5 | children: React.ReactNode 6 | } 7 | 8 | export default function Layout({ children }: LayoutProps) { 9 | const location = useLocation() 10 | 11 | const isActive = (path: string) => { 12 | return location.pathname === path ? 'active' : '' 13 | } 14 | 15 | return ( 16 |
17 |
18 |

React DevTools Playground

19 |

React 17 + SCSS + Node 14+ Compatibility Test

20 |
21 | 29 |
{children}
30 |
31 | ) 32 | } 33 | -------------------------------------------------------------------------------- /packages/react-devtools-client/src/composables/useComponentTreeHook.ts: -------------------------------------------------------------------------------- 1 | import type { InstallComponentTreeHookMessage } from '~/types/messages' 2 | import { useEffect, useRef } from 'react' 3 | 4 | /** 5 | * Custom hook to ensure component tree hook is installed 6 | * Only sends the installation request once when tree is not available 7 | */ 8 | export function useComponentTreeHook(tree: any) { 9 | const installRequestedRef = useRef(false) 10 | 11 | useEffect(() => { 12 | // Only request installation once and only if tree is not available 13 | if (!installRequestedRef.current && !tree) { 14 | installRequestedRef.current = true 15 | 16 | // Request the overlay (parent window) to install the component tree hook 17 | // Since we're in an iframe, we need to send message to parent 18 | const message: InstallComponentTreeHookMessage = { 19 | type: '__REACT_DEVTOOLS_INSTALL_COMPONENT_TREE_HOOK__', 20 | } 21 | window.parent.postMessage(message, '*') 22 | } 23 | }, [tree]) 24 | } 25 | -------------------------------------------------------------------------------- /packages/react-devtools-overlay/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-devtools-plus/overlay", 3 | "type": "module", 4 | "version": "0.4.0", 5 | "private": true, 6 | "author": "wzc520pyfm", 7 | "license": "MIT", 8 | "exports": { 9 | "./*": "./dist/*" 10 | }, 11 | "files": [ 12 | "dist" 13 | ], 14 | "engines": { 15 | "node": ">=v14.21.3" 16 | }, 17 | "scripts": { 18 | "build": "vite build", 19 | "stub": "vite build --watch" 20 | }, 21 | "dependencies": { 22 | "@react-devtools-plus/core": "workspace:^", 23 | "@react-devtools-plus/kit": "workspace:^", 24 | "@react-devtools-plus/scan": "workspace:^", 25 | "react": "catalog:", 26 | "react-dom": "catalog:" 27 | }, 28 | "devDependencies": { 29 | "@types/node": "catalog:", 30 | "@types/react": "catalog:", 31 | "@types/react-dom": "catalog:", 32 | "@vitejs/plugin-react": "catalog:", 33 | "rollup-plugin-external-globals": "^0.13.0", 34 | "typescript": "catalog:", 35 | "vite": "catalog:" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/react-devtools-client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-devtools-plus/client", 3 | "type": "module", 4 | "version": "0.4.0", 5 | "private": true, 6 | "author": "wzc520pyfm", 7 | "license": "MIT", 8 | "exports": { 9 | "./*": "./dist/*" 10 | }, 11 | "files": [ 12 | "dist" 13 | ], 14 | "engines": { 15 | "node": ">=v14.21.3" 16 | }, 17 | "scripts": { 18 | "build": "vite build", 19 | "stub": "vite build --watch" 20 | }, 21 | "dependencies": { 22 | "@react-devtools-plus/kit": "workspace:^", 23 | "@react-devtools-plus/ui": "workspace:^", 24 | "react": "catalog:", 25 | "react-dom": "catalog:", 26 | "react-router-dom": "^6.26.0", 27 | "vis-network": "^9.1.9" 28 | }, 29 | "devDependencies": { 30 | "@types/node": "catalog:", 31 | "@types/react": "catalog:", 32 | "@types/react-dom": "catalog:", 33 | "@unocss/reset": "catalog:", 34 | "@vitejs/plugin-react": "catalog:", 35 | "typescript": "catalog:", 36 | "unocss": "catalog:", 37 | "vite": "catalog:" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /packages/react-devtools/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * React DevTools Plugin 3 | * 4 | * A universal plugin for Vite and Webpack that provides: 5 | * - Component tree inspection 6 | * - React Scan performance monitoring 7 | * - Source code location tracking 8 | * - Open in editor functionality 9 | * 10 | * Supports: 11 | * - Webpack 4/5 12 | * - webpack-dev-server 3/4+ 13 | * - React 17/18+ 14 | * - Vite 4+ 15 | * 16 | * @example 17 | * ```ts 18 | * // Vite 19 | * import ReactDevTools from 'react-devtools-plus' 20 | * export default defineConfig({ 21 | * plugins: [ 22 | * ReactDevTools(), 23 | * ], 24 | * }) 25 | * 26 | * // Webpack 27 | * import { webpack as ReactDevTools } from 'react-devtools 28 | * module.exports = { 29 | * plugins: [ 30 | * ReactDevTools(), 31 | * ], 32 | * } 33 | * ``` 34 | */ 35 | 36 | export type { 37 | EnabledEnvironments, 38 | ResolvedPluginConfig, 39 | ScanConfig, 40 | SourcePathMode, 41 | } from './config/types.js' 42 | 43 | export { default, vite, webpack } from './unplugin.js' 44 | export type { ReactDevToolsPluginOptions } from './unplugin.js' 45 | -------------------------------------------------------------------------------- /packages/react-devtools-kit/src/messaging/presets/iframe/client.ts: -------------------------------------------------------------------------------- 1 | import { isBrowser } from '@react-devtools-plus/shared' 2 | import SuperJSON from 'superjson' 3 | import { MergeableChannelOptions } from '../../types/channel' 4 | import { __REACT_DEVTOOLS_KIT_IFRAME_MESSAGING_EVENT_KEY } from './context' 5 | 6 | export function createIframeClientChannel(): MergeableChannelOptions { 7 | if (!isBrowser) { 8 | return { 9 | post: () => {}, 10 | on: () => {}, 11 | } 12 | } 13 | 14 | return { 15 | post: data => window.parent.postMessage(SuperJSON.stringify({ 16 | event: __REACT_DEVTOOLS_KIT_IFRAME_MESSAGING_EVENT_KEY, 17 | data, 18 | }), '*'), 19 | on: handler => window.addEventListener('message', (event) => { 20 | try { 21 | const parsed = SuperJSON.parse<{ event: string, data: unknown }>(event.data) 22 | if (event.source === window.parent && parsed.event === __REACT_DEVTOOLS_KIT_IFRAME_MESSAGING_EVENT_KEY) { 23 | handler(parsed.data) 24 | } 25 | } 26 | catch (e) { 27 | // ignore parsing errors 28 | } 29 | }), 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 webfansplz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/ui-story/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-devtools-plus/ui-story", 3 | "type": "module", 4 | "version": "0.4.0", 5 | "private": true, 6 | "description": "Storybook for React DevTools UI components", 7 | "scripts": { 8 | "dev": "storybook dev -p 6006", 9 | "build": "storybook build", 10 | "preview": "http-server storybook-static -p 6006", 11 | "prepare:type": "echo 'Skipping type generation for ui-story'" 12 | }, 13 | "dependencies": { 14 | "@react-devtools-plus/ui": "workspace:*", 15 | "react": "catalog:", 16 | "react-dom": "catalog:" 17 | }, 18 | "devDependencies": { 19 | "@storybook/addon-essentials": "^8.5.3", 20 | "@storybook/addon-interactions": "^8.5.3", 21 | "@storybook/addon-links": "^8.5.3", 22 | "@storybook/blocks": "^8.5.3", 23 | "@storybook/react": "^8.5.3", 24 | "@storybook/react-vite": "^8.5.3", 25 | "@storybook/test": "^8.5.3", 26 | "@types/react": "catalog:", 27 | "@types/react-dom": "catalog:", 28 | "http-server": "^14.1.1", 29 | "storybook": "^8.5.3", 30 | "typescript": "catalog:", 31 | "vite": "catalog:" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/playground/my-devtools/src/index.ts: -------------------------------------------------------------------------------- 1 | import type { ReactDevToolsPluginOptions } from 'react-devtools-plus' 2 | import ReactDevTools from 'react-devtools-plus' 3 | import { getBuiltinPlugins } from './plugins' 4 | 5 | // Merge user options with our defaults 6 | function resolveOptions(options: ReactDevToolsPluginOptions = {}): ReactDevToolsPluginOptions { 7 | const builtinPlugins = getBuiltinPlugins() 8 | 9 | return { 10 | ...options, 11 | // Ensure scan is enabled by default if not provided 12 | scan: options.scan ?? { 13 | enabled: true, 14 | showToolbar: false, 15 | animationSpeed: 'fast', 16 | }, 17 | plugins: [ 18 | ...builtinPlugins, 19 | ...(options.plugins || []), 20 | ], 21 | } 22 | } 23 | 24 | export const vite = (options?: ReactDevToolsPluginOptions) => { 25 | return ReactDevTools.vite(resolveOptions(options)) 26 | } 27 | 28 | export const webpack = (options?: ReactDevToolsPluginOptions) => { 29 | return ReactDevTools.webpack(resolveOptions(options)) 30 | } 31 | 32 | export default { 33 | vite, 34 | webpack, 35 | } 36 | 37 | export type { ReactDevToolsPluginOptions } 38 | -------------------------------------------------------------------------------- /packages/react-devtools-kit/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-devtools-plus/kit", 3 | "type": "module", 4 | "version": "0.4.0", 5 | "author": "wzc520pyfm", 6 | "license": "MIT", 7 | "repository": { 8 | "directory": "packages/react-devtools-kit", 9 | "type": "git", 10 | "url": "git+https://github.com/vuejs/devtools.git" 11 | }, 12 | "exports": { 13 | ".": { 14 | "import": "./dist/index.js", 15 | "require": "./dist/index.cjs" 16 | } 17 | }, 18 | "main": "./dist/index.cjs", 19 | "module": "./dist/index.js", 20 | "files": [ 21 | "**.d.ts", 22 | "dist" 23 | ], 24 | "scripts": { 25 | "build": "tsdown --clean", 26 | "prepare:type": "tsdown --dts-only", 27 | "stub": "tsdown --watch --onSuccess 'tsdown --dts-only'" 28 | }, 29 | "dependencies": { 30 | "@react-devtools-plus/shared": "workspace:^", 31 | "birpc": "^2.6.1", 32 | "hookable": "^5.5.3", 33 | "mitt": "catalog:", 34 | "perfect-debounce": "catalog:", 35 | "superjson": "^2.2.2" 36 | }, 37 | "devDependencies": { 38 | "@types/node": "catalog:", 39 | "tsdown": "catalog:", 40 | "typescript": "^5.5.0" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /packages/playground/my-devtools/src/plugins/index.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path' 2 | import { fileURLToPath } from 'node:url' 3 | 4 | // Helper to get absolute path to plugin files 5 | // In a real package build, you might need to copy these files to dist or handle them differently 6 | // For this monorepo playground, we point to the source 7 | const __dirname = path.dirname(fileURLToPath(import.meta.url)) 8 | 9 | export const getBuiltinPlugins = () => { 10 | // When running from dist/index.js, __dirname is .../packages/playground/my-devtools/dist 11 | // We copy the plugins to dist/plugins during build 12 | const pluginPath = path.resolve(__dirname, './plugins/ContextInspector.tsx') 13 | 14 | return [ 15 | { 16 | name: 'context-inspector', 17 | view: { 18 | title: 'Inspector', 19 | // Eye icon 20 | icon: '', 21 | src: pluginPath, 22 | }, 23 | }, 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /packages/playground/react17-webpack4/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@react-devtools-plus/playground-react17-webpack4", 3 | "version": "0.0.0", 4 | "private": true, 5 | "engines": { 6 | "node": ">=16.0.0" 7 | }, 8 | "scripts": { 9 | "dev": "webpack-dev-server --mode development", 10 | "build": "webpack --mode production" 11 | }, 12 | "dependencies": { 13 | "react": "^17.0.2", 14 | "react-dom": "^17.0.2", 15 | "react-router-dom": "^5.3.4" 16 | }, 17 | "devDependencies": { 18 | "@babel/core": "^7.26.0", 19 | "@babel/preset-env": "^7.26.0", 20 | "@babel/preset-react": "^7.26.3", 21 | "@babel/preset-typescript": "^7.26.0", 22 | "@types/react": "^17.0.75", 23 | "@types/react-dom": "^17.0.25", 24 | "@types/react-router-dom": "^5.3.3", 25 | "babel-loader": "^8.2.5", 26 | "css-loader": "^5.2.7", 27 | "html-webpack-plugin": "^4.5.2", 28 | "react-devtools-plus": "workspace:*", 29 | "sass": "^1.83.4", 30 | "sass-loader": "^10.5.2", 31 | "style-loader": "^2.0.0", 32 | "typescript": "^5.9.3", 33 | "webpack": "^4.46.0", 34 | "webpack-cli": "^3.3.12", 35 | "webpack-dev-server": "^3.11.3" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "eslint.useFlatConfig": true, 3 | "prettier.enable": false, 4 | "editor.codeActionsOnSave": { 5 | "source.fixAll": "explicit" 6 | }, 7 | "editor.formatOnSave": false, 8 | // Silent the stylistic rules in you IDE, but still auto fix them 9 | "eslint.rules.customizations": [ 10 | { "rule": "style/*", "severity": "off" }, 11 | { "rule": "*-indent", "severity": "off" }, 12 | { "rule": "*-spacing", "severity": "off" }, 13 | { "rule": "*-spaces", "severity": "off" }, 14 | { "rule": "*-order", "severity": "off" }, 15 | { "rule": "*-dangle", "severity": "off" }, 16 | { "rule": "*-newline", "severity": "off" }, 17 | { "rule": "*quotes", "severity": "off" }, 18 | { "rule": "*semi", "severity": "off" } 19 | ], 20 | // Enable eslint for all supported languages 21 | "eslint.validate": [ 22 | "javascript", 23 | "javascriptreact", 24 | "typescript", 25 | "typescriptreact", 26 | "vue", 27 | "html", 28 | "markdown", 29 | "json", 30 | "jsonc", 31 | "yaml" 32 | ], 33 | "scss.lint.unknownAtRules": "ignore", 34 | "typescript.tsdk": "node_modules/typescript/lib", 35 | "cSpell.words": [ 36 | "Mergeable" 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /packages/react-devtools-ui/src/components/Checkbox/Checkbox.tsx: -------------------------------------------------------------------------------- 1 | import type { InputHTMLAttributes } from 'react' 2 | import { forwardRef } from 'react' 3 | import styles from './Checkbox.module.css' 4 | 5 | export interface CheckboxProps extends Omit, 'onChange'> { 6 | checked?: boolean 7 | onChange?: (checked: boolean) => void 8 | label?: string 9 | } 10 | 11 | export const Checkbox = forwardRef(({ checked, onChange, label, disabled, className = '', ...props }, ref) => { 12 | return ( 13 | 30 | ) 31 | }) 32 | 33 | Checkbox.displayName = 'Checkbox' 34 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "jsx": "react-jsx", 5 | "lib": ["esnext", "dom"], 6 | "module": "esnext", 7 | "moduleResolution": "bundler", 8 | "paths": { 9 | "@react-devtools-plus/shared": ["./packages/shared/src/index.ts"], 10 | "@react-devtools-plus/kit": ["./packages/react-devtools-kit/src/index.ts"], 11 | "@react-devtools-plus/client": ["./packages/react-devtools-client/src/index.ts"], 12 | "@react-devtools-plus/overlay": ["./packages/react-devtools-overlay/src/index.ts"], 13 | "react-devtools-plus": ["./packages/react-devtools/src/index.ts"] 14 | }, 15 | "resolveJsonModule": true, 16 | "types": [ 17 | "chrome", 18 | "vite/client", 19 | "vitest/globals" 20 | ], 21 | "allowJs": true, 22 | "strict": true, 23 | "strictNullChecks": true, 24 | "noImplicitAny": false, 25 | // We use tsup/vite instead of tsc to build the package, so we don't need to care about this option. 26 | // Add outDir option to avoid tsconfig error in monorepo. 27 | "outDir": "dist", 28 | "esModuleInterop": true 29 | }, 30 | "exclude": [ 31 | "**/vite/src/overlay/**", 32 | "**/dist/**", 33 | "**/node_modules/**", 34 | "**/**/*.js" 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /packages/playground/react-webpack/README.md: -------------------------------------------------------------------------------- 1 | # React Webpack Playground 2 | 3 | This is a playground for React applications using Webpack with React DevTools support via unplugin. 4 | 5 | ## Features 6 | 7 | - ✅ React DevTools support via `react-devtools/webpack` 8 | - ✅ Hot Module Replacement (HMR) 9 | - ✅ Development server with DevTools client 10 | 11 | ## Usage 12 | 13 | ```bash 14 | # Install dependencies 15 | pnpm install 16 | 17 | # Start development server 18 | pnpm dev 19 | 20 | # Build for production 21 | pnpm build 22 | ``` 23 | 24 | ## React DevTools 25 | 26 | The playground uses the unplugin-based React DevTools plugin, which supports both Vite and Webpack. 27 | 28 | To configure DevTools, edit `webpack.config.js`: 29 | 30 | ```javascript 31 | const ReactDevToolsPlugin = require('react-devtools/webpack') 32 | 33 | module.exports = { 34 | plugins: [ 35 | ReactDevToolsPlugin({ 36 | enabledEnvironments: ['development', 'test'], 37 | }), 38 | ], 39 | } 40 | ``` 41 | 42 | ## How It Works 43 | 44 | The plugin uses [unplugin](https://github.com/unjs/unplugin) to provide a unified plugin interface that works with both Vite and Webpack. This means: 45 | 46 | - Same API for both build tools 47 | - Consistent behavior across environments 48 | - Easy migration between Vite and Webpack 49 | -------------------------------------------------------------------------------- /packages/react-devtools-ui/src/components/Card/Card.module.css: -------------------------------------------------------------------------------- 1 | .card { 2 | background-color: var(--color-bg-elevated); 3 | border-radius: var(--radius-lg); 4 | transition: all var(--duration-base) var(--timing-easeInOut); 5 | } 6 | 7 | .card.bordered { 8 | border: 1px solid var(--color-border-base); 9 | } 10 | 11 | .card.hoverable { 12 | cursor: pointer; 13 | } 14 | 15 | .card.hoverable:hover { 16 | border-color: var(--color-border-hover); 17 | box-shadow: var(--shadow-md); 18 | transform: translateY(-2px); 19 | } 20 | 21 | .header { 22 | padding: var(--spacing-4) var(--spacing-4) var(--spacing-2); 23 | border-bottom: 1px solid var(--color-border-base); 24 | } 25 | 26 | .title { 27 | margin: 0; 28 | font-size: var(--font-size-base); 29 | font-weight: var(--font-weight-semibold); 30 | color: var(--color-text-primary); 31 | } 32 | 33 | .body { 34 | color: var(--color-text-secondary); 35 | } 36 | 37 | /* Padding variants */ 38 | .padding-none { 39 | padding: 0; 40 | } 41 | 42 | .padding-sm { 43 | padding: var(--spacing-2); 44 | } 45 | 46 | .padding-md { 47 | padding: var(--spacing-4); 48 | } 49 | 50 | .padding-lg { 51 | padding: var(--spacing-6); 52 | } 53 | 54 | /* When there's a header, remove top padding from body */ 55 | .card:has(.header) .body { 56 | padding-top: 0; 57 | } 58 | -------------------------------------------------------------------------------- /packages/react-devtools-kit/src/messaging/presets/iframe/server.ts: -------------------------------------------------------------------------------- 1 | import { isBrowser } from '@react-devtools-plus/shared' 2 | import SuperJSON from 'superjson' 3 | import { MergeableChannelOptions } from '../../types/channel' 4 | import { __REACT_DEVTOOLS_KIT_IFRAME_MESSAGING_EVENT_KEY, getIframeServerContext } from './context' 5 | 6 | export function createIframeServerChannel(): MergeableChannelOptions { 7 | if (!isBrowser) { 8 | return { 9 | post: () => {}, 10 | on: () => {}, 11 | } 12 | } 13 | 14 | return { 15 | post: (data) => { 16 | const iframe = getIframeServerContext() 17 | iframe?.contentWindow?.postMessage(SuperJSON.stringify({ 18 | event: __REACT_DEVTOOLS_KIT_IFRAME_MESSAGING_EVENT_KEY, 19 | data, 20 | }), '*') 21 | }, 22 | on: (handler) => { 23 | window.addEventListener('message', (event) => { 24 | const iframe = getIframeServerContext() 25 | try { 26 | const parsed = SuperJSON.parse<{ event: string, data: unknown }>(event.data) 27 | if (event.source === iframe?.contentWindow && parsed.event === __REACT_DEVTOOLS_KIT_IFRAME_MESSAGING_EVENT_KEY) { 28 | handler(parsed.data) 29 | } 30 | } 31 | catch (e) { 32 | // ignore parsing errors 33 | } 34 | }) 35 | }, 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/react-devtools-ui/src/components/Switch/Switch.tsx: -------------------------------------------------------------------------------- 1 | import type { FC, InputHTMLAttributes } from 'react' 2 | import styles from './Switch.module.css' 3 | 4 | export type SwitchSize = 'sm' | 'md' | 'lg' 5 | 6 | export interface SwitchProps extends Omit, 'onChange' | 'size'> { 7 | checked?: boolean 8 | onChange?: (checked: boolean) => void 9 | label?: string 10 | size?: SwitchSize 11 | } 12 | 13 | export const Switch: FC = ({ 14 | checked, 15 | onChange, 16 | label, 17 | className = '', 18 | disabled, 19 | size = 'md', 20 | ...props 21 | }) => { 22 | const containerClass = [ 23 | styles.switch, 24 | disabled && styles.disabled, 25 | className, 26 | ].filter(Boolean).join(' ') 27 | 28 | const trackClass = [ 29 | styles.track, 30 | styles[`size-${size}`], 31 | ].filter(Boolean).join(' ') 32 | 33 | return ( 34 |