vue-devtools-plugin

repository·master·Indexed 43 days ago

https://github.com/zippowxk/vue-devtools-plugin

A plugin for vConsole and Eruda that ports official Vue.js DevTools to mobile environments, allowing developers to debug Vue 2 and Vue 3 applications on mobile devices or within mobile browsers like WeChat. Includes support for vConsole via vue-vconsole-devtools and Eruda via eruda-vue-devtools.

Tokens
37.7K
Snippets
132
Records
153
Agent score
50%

What's inside vue-devtools-plugin

  1. How to add custom Timeline layers and events

    master

    You can extend the Vue Devtools Timeline by adding custom layers and events:

    1. Register a layer: Use addTimelineLayer to define a new layer with a unique id, color, and label.
    2. Send events: Use addTimelineEvent to record occurrences. Each event requires a layerId and an event object containing a time (use api.now()) and data.
    3. Group events: To group multiple events into a single pill-shaped rectangle in the UI, assign the same groupId to the event object of all related events. This allows the inspector to show the total duration of the group.

    Early Proxy: If you need to send timeline events before the Devtools are fully connected (e.g., during early app initialization), set the enableEarlyProxy: true option in setupDevtoolsPlugin. This provides a proxy api that buffers calls until the real API is available.

    // Register layer
    api.addTimelineLayer({
      id: 'my-layer',
      color: 0xff984f,
      label: 'Awesome!'
    })
    
    // Send grouped event
    const groupId = 'task-1'
    api.addTimelineEvent({
      layerId: 'my-layer',
      event: {
        time: api.now(),
        data: { info: 'starting' },
        groupId
      }
    })
  2. Implement the tree and state hooks for custom inspectors

    master

    To make a custom inspector functional, you must implement hooks to provide the tree structure and the state of selected nodes. Always check payload.inspectorId to ensure you only respond to your specific inspector.

    Providing the Tree Structure (on.getInspectorTree)

    This hook is called when the devtools needs to load the tree. You must assign an array of nodes to payload.rootNodes. Each node can have an id, label, children, and tags (with label, textColor, backgroundColor, and tooltip).

    Providing Node State (on.getInspectorState)

    This hook provides the data for the currently selected node. The payload.state should be an object where keys are section names and values are arrays of field objects. Fields include type, key, value, and an optional editable boolean.

    Handling Edits (on.editInspectorState)

    If you set editable: true on a field, use this hook to apply changes made by the user. The payload.set(state) helper function simplifies applying edits to your state object.

    // 1. Provide the tree
    api.on.getInspectorTree(payload => {
      if (payload.inspectorId === 'test-inspector') {
        payload.rootNodes = [
          {
            id: 'root',
            label: 'Root Node',
            children: [{ id: 'child', label: 'Child Node' }]
          }
        ]
      }
    })
    
    // 2. Provide the state
    api.on.getInspectorState(payload => {
      if (payload.inspectorId === 'test-inspector') {
        if (payload.nodeId === 'root') {
          payload.state = {
            'info': [
              { key: 'foo', value: 'bar', editable: true }
            ]
          }
        }
      }
    })
    
    // 3. Handle edits
    api.on.editInspectorState(payload => {
      if (payload.inspectorId === 'test-inspector') {
        if (payload.nodeId === 'root') {
          payload.set(myState)
        }
      }
    })
  3. How to create a custom inspector

    master

    Vue Devtools allows plugins to introduce new inspectors alongside the default Components inspector. To implement a custom inspector, you must follow three steps:

    1. Register the inspector: Use addInspector to define the inspector's identity, label, and icon (using Material Icon codes).
    2. Populate the tree: Handle the getInspectorTree hook to define the hierarchical structure of nodes displayed in the inspector's sidebar/top menu.
    3. Provide state: Handle the getInspectorState hook to provide detailed information for a specific selected node.

    Note: Always verify that the payload.inspectorId matches your registered inspector ID within the hooks to avoid processing data for other inspectors.

    const inspectorId = 'my-awesome-plugin'
    
    // 1. Register
    api.addInspector({
      id: inspectorId,
      label: 'Awesome!',
      icon: 'pets',
    })
    
    // 2. Handle Tree
    api.on.getInspectorTree((payload, context) => {
      if (payload.inspectorId === inspectorId) {
        payload.rootNodes = [
          {
            id: 'root',
            label: 'Awesome root',
            children: [{ id: 'child-1', label: 'Child 1' }]
          }
        ]
      }
    })
    
    // 3. Handle State
    api.on.getInspectorState((payload, context) => {
      if (payload.inspectorId === inspectorId && payload.nodeId === 'child-1') {
        payload.state = {
          'my section': [{ key: 'cat', value: 'meow' }]
        }
      }
    })
  4. How Vue Devtools Plugins work

    master

    A Vue Devtools Plugin is registered from your Vue package code within the user's application. It communicates with the Vue Devtools Backend via the public API.

    Key Components:

    • Backend: A script injected into the web page when Devtools are opened. It handles Vue application registration and communication with the Frontend.
    • Frontend: The Vue application displayed in the browser's devtools pane.
    • Hook: A global variable added to the page that allows the Vue application and your plugin to send messages to the Backend.

    API Categories:

    • Components Inspector: Allows your plugin to add information to the component tree and state.
    • Custom Inspectors: Allows you to add new inspectors to display arbitrary state (e.g., routes, store state).
    • Timeline: Allows you to add custom layers and send events.
  5. Profile devtools performance

    master

    If you encounter performance issues while using the devtools, follow these steps to create a profiling session and share the results with the development team for investigation.

    1. Setup Environment

    Clone and set up the devtools repository following the development instructions in the contributing guide.

    2. Run Chrome with web security disabled

    The devtools development shell uses an iframe to mimic the page being inspected. To allow cross-domain inspection (e.g., from localhost to the iframe content), you must run Chrome with web security disabled.

    Warning: Do not browse to any other websites while using this Chrome instance, as security features are disabled.

    /path/to/chrome --disable-web-security --disable-site-isolation-trials --user-data-dir="temp-chrome-data"

    3. Open the Dev Shell

    1. Ensure you have run the build:watch and dev:vue3 scripts.
    2. In the specialized Chrome window, navigate to http://localhost:8090.
    3. Use the toolbar at the top of the devtools to change the target URL to the application you wish to inspect.

    4. Create a Profiling Session

    1. Open the Chrome DevTools and navigate to the Performance tab.
    2. Click the Record button to start a recording.
    3. Reproduce the performance issue by interacting with both your application and the devtools for 10 to 20 seconds.
    4. Click the Stop button to end the recording.
    5. Click the Save profile... button to export the profiling data file.

    5. Share the Profiling Data

    To report the issue, post a comment on the official discussion thread including:

    • The output of npx envinfo --system --browsers (ensuring OS and Chrome versions are included).
    • The Vue Devtools version (found in the Chrome Extensions tab).
    • The exported profiling data file (drag and drop into the comment box).
  6. Use vue-remote-devtools via global package (HTML Script Tag)

    master

    If you installed @vue/devtools globally, start the application by running vue-devtools in your terminal. Then, add a <script> tag to the <head> section of your application.

    To debug a device remotely (e.g., a mobile phone on the same network), you must configure the __VUE_DEVTOOLS_HOST__ and __VUE_DEVTOOLS_PORT__ global variables before the devtools script loads.

    <!-- Standard local debugging -->
    <script src="http://localhost:8098"></script>
    
    <!-- Remote device debugging (e.g. mobile) -->
    <script>
      window.__VUE_DEVTOOLS_HOST__ = '<your-local-ip>' // e.g., '192.168.x.x'
      window.__VUE_DEVTOOLS_PORT__ = '<devtools-port>' // default: 8098
    </script>
    <script src="http://<your-local-ip>:8098"></script>
  7. Enable Vue devtools for local HTML files (file:// protocol)

    master

    If you are opening an HTML file directly in Google Chrome and see the "Download the Vue Devtools for a better development experience" message, you must grant the extension permission to access local files:

    1. Right-click on the vue-devtools icon in your browser toolbar.
    2. Click Manage Extensions.
    3. Find vue-devtools in your extensions list.
    4. Check the box labeled Allow access to file URLs.
  8. Build your plugin with Rollup

    master

    Rollup is recommended for compiling your package, especially if you use .vue files.

    1. Install Rollup dependencies

    yarn add -D rollup rollup-plugin-vue @rollup/plugin-commonjs @rollup/plugin-node-resolve @rollup/plugin-replace rollup-plugin-terser pascalcase rimraf

    2. Configure package.json exports

    To support multiple environments (CJS, ESM, Browser), configure the main, module, unpkg, and exports fields in your package.json.

    {
      "name": "my-plugin",
      "version": "0.0.0",
      "main": "dist/my-plugin.cjs.js",
      "module": "dist/my-plugin.esm-bundler.js",
      "unpkg": "dist/my-plugin.global.js",
      "jsdelivr": "dist/my-plugin.global.js",
      "exports": {
        ".": {
          "require": "./dist/my-plugin.cjs.js",
          "browser": "./dist/my-plugin.esm-browser.js",
          "import": "./dist/my-plugin.esm-bundler.js",
          "module": "./dist/my-plugin.esm-bundler.js"
        },
        "./package.json": "./package.json"
      },
      "sideEffects": false,
      "scripts": {
        "build": "rimraf dist && rollup -c rollup.config.js"
      }
    }