React Dev Inspector
Introduction
This package allows users to jump to local IDE code directly from browser React component by just a simple click, which is similar to Chrome inspector but more advanced.
Preview
online demo: https://react-dev-inspector.zthxxx.me
press hotkey (ctrl⌃ + shift⇧ + commmand⌘ + c
), then click the HTML element you wish to inspect.
screen record gif (8M size):
Installation
npm i -D react-dev-inspector
Usage
for VSCode only, but simple without any other configuration
Works with almost all react frameworks such as
Vite,
Next.js,
Create React App,
Umi3,
Ice.js,
or any other which use @babel/plugin-transform-react-jsx-source in builtin.
Just follow the component code below:
import React from 'react'
import { Inspector, InspectParams } from 'react-dev-inspector'
const isDev = process.env.NODE_ENV === 'development'
export const Layout = () => {
return (
<>
<YourComponent />
{isDev && (
<Inspector
// props see docs:
// https://github.com/zthxxx/react-dev-inspector#inspector-component-props
keys={['control', 'shift', 'command', 'c']}
disableLaunchEditor={true}
onClickElement={({ codeInfo }: InspectParams) => {
if (!codeInfo?.absolutePath) return
const { absolutePath, lineNumber, columnNumber } = codeInfo
// you can change the url protocol if you are using in Web IDE
window.open(`vscode://file/${absolutePath}:${lineNumber}:${columnNumber}`)
}}
>
)}
</>
)
}
Whether you use vscode://
, webstorm://
or otherwise, it solidifies in code.
sometime you want it infer which is the current local IDE you are using now.
But for generally infer current local IDE, need some server-side configuration.
At this time, follow those TWO steps below:
1. Add Inspector React Component
import React from 'react'
import { Inspector, InspectParams } from 'react-dev-inspector'
const isDev = process.env.NODE_ENV === 'development'
export const Layout = () => {
return (
<>
<YourComponent />
{isDev && (
<Inspector
// props see docs:
// https://github.com/zthxxx/react-dev-inspector#inspector-component-props
keys={['control', 'shift', 'command', 'c']}
onHoverElement={(inspect: InspectParams) => {}}
onClickElement={(inspect: InspectParams) => {}}
>
)}
</>
)
}
2. Set up Inspector Config
You should add:
- an inspector babel plugin, to inject source code location info
react-dev-inspector/plugins/babel
- an server api middleware, to open local IDE
import { launchEditorMiddleware } from 'react-dev-inspector/plugins/webpack'
to your current project development config.
Such as add babel plugin into your .babelrc
or webpack babel-loader
config,
add api middleware into your webpack-dev-server
config or other server setup.
There are some example ways to set up, please pick the one fit your project best.
In common cases, if you're using webpack, you can see #raw-webpack-config,
If your project happen to use vite / nextjs / create-react-app and so on, you can also try out our integrated plugins / examples with
raw webpack config
Support webpack v4 and v5, examples see:
.babelrc.js
module.exports = {
plugins: [
'react-dev-inspector/plugins/babel',
],
}
webpack.config.ts
import type { Configuration } from 'webpack'
import { ReactInspectorPlugin } from 'react-dev-inspector/plugins/webpack'
const config: Configuration = {
plugins: [
new ReactInspectorPlugin(),
],
}
However, if you want more manully config with webpack-dev-server
, here are some equivalent:
webpack.config.ts
import type { Configuration } from 'webpack'
import { launchEditorMiddleware } from 'react-dev-inspector/plugins/webpack'
const config: Configuration = {
devServer: {
setupMiddlewares: (middlewares, devServer) => {
middlewares.unshift(launchEditorMiddleware)
return middlewares
},
before: (app, server, compiler) => {
app.use(launchEditorMiddleware)
},
},
}
usage with Vite2
example project see: https://github.com/zthxxx/react-dev-inspector/tree/master/examples/vite2
vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { inspectorServer } from 'react-dev-inspector/plugins/vite'
export default defineConfig({
plugins: [
react(),
inspectorServer(),
],
})
use Next.js Custom Server + Customizing Babel Config
example project see: https://github.com/zthxxx/react-dev-inspector/tree/master/examples/nextjs
server.js
...
const {
queryParserMiddleware,
launchEditorMiddleware,
} = require('react-dev-inspector/plugins/webpack')
app.prepare().then(() => {
createServer((req, res) => {
const middlewares = [
queryParserMiddleware,
launchEditorMiddleware,
(req, res) => handle(req, res),
]
const middlewarePipeline = middlewares.reduceRight(
(next, middleware) => (
() => { middleware(req, res, next) }
),
() => {},
)
middlewarePipeline()
}).listen(PORT, (err) => {
if (err) throw err
console.debug(`> Ready on http://localhost:${PORT}`)
})
})
package.json
"scripts": {
- "dev": "next dev",
+ "dev": "node server.js",
"build": "next build"
}
.babelrc.js
module.exports = {
plugins: [
'react-dev-inspector/plugins/babel',
],
}
usage with create-react-app
create-react-app + react-app-rewired + customize-cra example config-overrides.js
:
example project see: https://github.com/zthxxx/react-dev-inspector/tree/master/examples/cra
Support create-react-app v4, v5, example config see:
config-overrides.js
const {
launchEditorMiddleware,
ReactInspectorPlugin,
} = require('react-dev-inspector/plugins/webpack')
const {
override,
overrideDevServer,
addBabelPlugin,
} = require('customize-cra')
module.exports = {
webpack: override(
addBabelPlugin([
'react-dev-inspector/plugins/babel',
{
excludes: [
/xxxx-want-to-ignore/,
],
},
]),
addWebpackPlugin(
new ReactInspectorPlugin(),
),
),
devServer: overrideDevServer(
serverConfig => {
serverConfig.setupMiddlewares = (middlewares) => {
middlewares.unshift(launchEditorMiddleware)
return middlewares
}
return serverConfig
},
),
}
usage with Umi3
example project see: https://github.com/zthxxx/react-dev-inspector/tree/master/examples/umi3
.umirc.dev.ts
import { defineConfig } from 'umi'
export default defineConfig({
plugins: [
'react-dev-inspector/plugins/umi/react-inspector',
],
inspectorConfig: {
excludes: [],
},
})
usage with Umi2
.umirc.dev.ts
import { launchEditorMiddleware } from 'react-dev-inspector/plugins/webpack'
export default {
extraBabelPlugins: [
'react-dev-inspector/plugins/babel',
],
chainWebpack(config, { webpack }) {
const originBefore = config.toConfig().devServer
config.devServer.before((app, server, compiler) => {
app.use(launchEditorMiddleware)
originBefore?.before?.(app, server, compiler)
})
return config
},
}
build.json
{
"plugins": [
"react-dev-inspector/plugins/ice",
]
}
Examples Project Code
- vite2
- next.js
- create-react-app
- umi3
Configuration
<Inspector>
Component Props
checkout TS definition under react-dev-inspector/es/Inspector.d.ts
.
interface InspectParams {
element: HTMLElement,
fiber?: React.Fiber,
codeInfo?: {
lineNumber: string,
columnNumber: string,
relativePath?: string,
absolutePath?: string,
},
name?: string,
}
Inspector Babel Plugin Options
interface InspectorPluginOptions {
cwd?: string,
excludes?: (string | RegExp)[],
}
Inspector Loader Props
interface InspectorConfig {
excludes?: (string | RegExp)[],
babelPlugins?: ParserPlugin[],
babelOptions?: ParserOptions,
}
IDE / Editor config
This package uses react-dev-utils
to launch your local IDE application, but, which one will be open?
In fact, it uses an environment variable named REACT_EDITOR
to specify an IDE application, but if you do not set this variable, it will try to open a common IDE that you have open or installed once it is certified.
For example, if you want it always open VSCode when inspection clicked, set export REACT_EDITOR=code
in your shell.
VSCode
-
install VSCode command line tools, see the official docs
-
set env to shell, like .bashrc
or .zshrc
export REACT_EDITOR=code
WebStorm
OR
-
install WebStorm command line tools
-
then set env to shell, like .bashrc
or .zshrc
export REACT_EDITOR=webstorm
Vim
Yes! you can also use vim if you want, just set env to shell
export REACT_EDITOR=vim
How It Works
Analysis of Theory
License
MIT LICENSE