1.0.0 • Published 3 years ago

react-element-inspector v1.0.0

Weekly downloads
4
License
MIT
Repository
github
Last release
3 years ago

Preview

Forked from https://github.com/zthxxx/react-dev-inspector, but supports react15

Online demo: https://react-dev-inspector.zthxxx.me

Screen record (gif 8M):

inspector-gif

Install

npm i -D react-dev-inspector

Usage

There are 3 steps required to use react-dev-inspector, here will list some typical manual config of webpack, and this lib also provide some integrated plugins to make you easy to use

  • Step 1 - Compile Time
    • webpack loader inject source file path/line/column to JSX data attributes props (use babel)
    • webpack plugin inject PWD (current working directory) env define for runtime
  • Step 2 - Web React Runtime

    • component Inspector Component in react, for listen hotkeys, and request api to dev-server for open IDE
  • Step 3 - Dev-server Side

    • middleware createLaunchEditorMiddleware in webpack dev-server (or other dev-server), to open file in IDE according to the request.

      Only need in development mode,and you want to open IDE when click a component element.

      Not need in prod mode, or you just want inspect dom without open IDE (set disableLaunchEditor={false} to Inspector component)

Typical webpack config

Include step-1 and step-3, compile Time and dev-server Side

import { Configuration, DefinePlugin } from 'webpack'
import { createLaunchEditorMiddleware } from 'react-dev-inspector/plugins/webpack'


const config: Configuration = {
  // ...
  
  /**
   * [compile time] for inject source code file info
   */
  module: {
    rules: [
      {
        test: /\.[jt]sx$/,
        exclude: [
          /node_modules/,
          /file-you-want-exclude/,
        ],
        use: [
          {
            loader: 'react-dev-inspector/plugins/webpack/inspector-loader',
            options: [{
              // loader options type and docs see below
              exclude: [
                'xxx-file-will-be-exclude',
                /regexp-to-match-file /,
              ],
              babelPlugins: [],
              babelOptions: {},
            }],
          },
        ],
      },
    ],
  },

  /**
   * [compile time] for inject current working directory which used in web page runtime
   */
  plugins: [
    new DefinePlugin({
      'process.env.PWD': JSON.stringify(process.cwd()),
    }),
  ],

  /**
   * [server side] webpack dev server side middleware for launch IDE app
   */
  devServer: {
    before: (app) => {
      app.use(createLaunchEditorMiddleware())
    },
  },
}

Usage with Webpack Chain

Include step 1 and step 3, it's almost equivalent to Typical webpack config above,

but it will NOT override devServer.before, just add middleware before origin devServer.before

import { inspectorChainWebpack } from 'react-dev-inspector/plugins/webpack'


webpackChainConfig = inspectorChainWebpack(webpackChainConfig, {
  // loader options type and docs see below
  exclude: [],
  babelPlugins: [],
  babelOptions: {},
})

Usage with Umi3

Include step 1 and step 3, also equivalent to Usage with Webpack Chain

Example .umirc.dev.ts:

// https://umijs.org/config/
import { defineConfig } from 'umi'

export default defineConfig({
  plugins: [
    'react-dev-inspector/plugins/umi/react-inspector',
  ],
  inspectorConfig: {
    // loader options type and docs see below
    exclude: [],
    babelPlugins: [],
    babelOptions: {},
  },
})

Usage with Umi2

Include step 1 and step 3

Example .umirc.dev.js:

import { inspectorChainWebpack } from 'react-dev-inspector/plugins/webpack'

export default {
  // ...
  chainWebpack(config) {
    inspectorChainWebpack(config, {
      // ... options
    })
    return config
  },
 
  /**
   * And you need to set `false` to `dll` in `umi-plugin-react`,
   * becase these is a umi2 bug that `dll` cannot work with `devServer.before`
   *
   * https://github.com/umijs/umi/issues/2599
   * https://github.com/umijs/umi/issues/2161
   */
}

Use in React

Include step-2, react runtime

import React from 'react'
import { Inspector, InspectParams } from 'react-dev-inspector'

const InspectorWrapper = process.env.NODE_ENV === 'development'
  ? Inspector
  : React.Fragment

export const Layout = () => { 
  // ...
  
  return (
    <InspectorWrapper
      // props docs see below
      keys={['control', 'shift', 'command', 'c']}
      disableLaunchEditor={false}
      onHoverElement={(params: InspectParams) => {}}
      onClickElement={(params: InspectParams) => {}}
    >
     <YourComponent>
       ...
     </YourComponent>
    </InspectorWrapper>
  )
}

after <Inspector> component was mounted,you can use window.__REACT_DEV_INSPECTOR_TOGGLE__() to toggle inspector.

Config of Loader / Component / IDE

Inspector Loader Props

// import type { ParserPlugin, ParserOptions } from '@babel/parser'
// import type { InspectorConfig } from 'react-dev-inspector/plugins/webpack'

interface InspectorConfig {
  /** patterns to exclude matched files */
  exclude?: (string | RegExp)[],
  /**
   * add extra plugins for babel parser
   * default is ['typescript', 'jsx', 'decorators-legacy', 'classProperties']
   */
  babelPlugins?: ParserPlugin[],
  /** extra babel parser options */
  babelOptions?: ParserOptions,
}

<Inspector> Component Props

typescript define you can see in react-dev-inspector/es/Inspector.d.ts

PropertyDescriptionTypeDefault
keysinspector toggle hotkeyssupported keys see: https://github.com/jaywcjlove/hotkeys#supported-keysstring[]['control', 'shift', 'command', 'c']
disableLaunchEditorwhether disable click react component to open IDE for view component code(launchEditor by default only support be used with react-dev-inpector plugins in dev)booleanfalse
onHoverElementtriggered while inspector start and mouse hover in a HTMLElement(params: InspectParams) => void-
onClickElementtriggered while inspector start and mouse click on a HTMLElement(params: InspectParams) => void-
// import type { InspectParams } from 'react-dev-inspector'

interface InspectParams {
  /** hover / click event target dom element */
  element: HTMLElement,
  /** nearest named react component fiber for dom element */
  fiber?: React.Fiber,
  /** source file line / column / path info for react component */
  codeInfo?: {
    lineNumber: string,
    columnNumber: string,
    relativePath: string,
  },
  /** react component name for dom element */
  name?: string,
}

IDE / Editor config

this lib use react-dev-utils to launch your local IDE app, but which one app will be open?

In fact, it uses an environment variable named REACT_EDITOR, but if you not set this variable, it will guess a IDE in what you opened now or what you installed.

For example, if you want it always open VSCode when inspect clicked, set export REACT_EDITOR=code in your shell.

VSCode

  • install VSCode command line tools, see the official docs install-vscode-cli

  • set env to shell, like .bashrc or .zshrc

    export REACT_EDITOR=code

WebStorm

  • just set env with an absolute path to shell, like .bashrc or .zshrc (only MacOS)
    export REACT_EDITOR='/Applications/WebStorm.app/Contents/MacOS/webstorm'

OR

  • install WebStorm command line tools install-webstorm-cli

  • then set env to shell, like .bashrc or .zshrc

    export REACT_EDITOR=webstorm

Vim

yes, you can also use vim if you prefer it, just set env to shell

export REACT_EDITOR=vim

Example Project Code

code see: https://github.com/zthxxx/react-dev-inspector/tree/master/site

project preview: https://react-dev-inspector.zthxxx.me

Analysis of Theory

License

MIT LICENSE