Skip to content

fix(devtools-kit): support JSX/TSX components in component inspector#1101

Closed
NikhilVerma wants to merge 3 commits into
vuejs:mainfrom
NikhilVerma:fix/jsx-component-inspector
Closed

fix(devtools-kit): support JSX/TSX components in component inspector#1101
NikhilVerma wants to merge 3 commits into
vuejs:mainfrom
NikhilVerma:fix/jsx-component-inspector

Conversation

@NikhilVerma
Copy link
Copy Markdown

@NikhilVerma NikhilVerma commented May 16, 2026

Summary

The component inspector had two bugs that broke JSX/TSX support:

  1. Click-to-select picker didn't work for JSX/TSX components (component-highlighter/index.ts)

    inspectFn only checked e.target.__vueParentComponent on the exact hovered element. JSX and functional components typically only set __vueParentComponent on their root DOM element, not every descendant. Fixed by walking up the DOM tree until a component instance is found.

  2. "Open in Editor" button missing for JSX/TSX components (packages/vite/src/vite.ts)

    @vitejs/plugin-vue-jsx injects __hmrId on Vue components it identifies but never injects __file. The devtools "Open in Editor" button is gated on instance.type.__file, so it was always hidden for JSX/TSX. Fixed by adding a post-enforce Vite transform that piggybacks on the __hmrId assignments already injected by the vue-jsx plugin: for each LocalName.__hmrId = ..., we prepend LocalName.__file = "/abs/path/to/file.tsx".

  3. Component names mangled for JSX/TSX files (component/utils/index.ts)

    getComponentFileName only stripped .vue from __file paths, so .jsx/.tsx components showed their raw filename (e.g. MyButton.jsx instead of MyButton). Fixed by handling all three extensions. Also extends the index name suppression to index.jsx/index.tsx barrel files.

Changes

  • packages/vite/src/vite.ts — post-transform plugin to inject __file on JSX/TSX components recognised by @vitejs/plugin-vue-jsx
  • packages/devtools-kit/src/core/component-highlighter/index.ts — walk up the DOM tree in inspectFn
  • packages/devtools-kit/src/core/component/utils/index.ts — handle .jsx/.tsx extensions in name resolution

Tests

  • __tests__/component/utils.test.ts — unit tests for getComponentName / getInstanceName with .jsx/.tsx files
  • __tests__/component/highlighter.test.ts — DOM-level tests verifying the highlight overlay is created when __vueParentComponent is only on a parent element (the JSX case)

Test plan

  • pnpm test — all tests pass
  • Loaded the unpacked Chrome extension and verified:
    • Component picker highlights JSX/TSX components on hover and selects on click
    • "Open in Editor" button appears for TSX components in the component tree panel
    • Existing SFC component behaviour is unaffected

Two bugs prevented the click-to-inspect picker from working with JSX/TSX
components:

1. `inspectFn` only checked `e.target.__vueParentComponent` on the exact
   clicked element. JSX and functional components often only set this
   property on their root element, not on every inner child, so clicking
   a child element produced no match. Fixed by walking up the DOM tree
   until a component instance is found.

2. `getComponentFileName` only stripped the `.vue` extension when
   deriving a display name from `__file`. Components in `.jsx`/`.tsx`
   files showed up with the raw filename (e.g. `MyButton.jsx` instead of
   `MyButton`). Fixed by handling all three extensions.

Also suppresses the `index` name for `index.jsx` and `index.tsx` barrel
files, matching the existing behaviour for `index.vue`.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@netlify
Copy link
Copy Markdown

netlify Bot commented May 16, 2026

Deploy Preview for vue-devtools-docs canceled.

Name Link
🔨 Latest commit 1d89d77
🔍 Latest deploy log https://app.netlify.com/projects/vue-devtools-docs/deploys/6a0a74b83394d30008efe53a

NikhilVerma and others added 2 commits May 18, 2026 07:29
@vitejs/plugin-vue-jsx marks every Vue component it finds with __hmrId
but never sets __file, so the devtools "Open in Editor" button was hidden
for all JSX/TSX components (the button is gated on instance.type.__file).

Add a post-enforce Vite transform that piggybacks on those __hmrId
assignments: for each `LocalName.__hmrId = ...` the plugin has already
injected, we prepend `LocalName.__file = "/abs/path/to/file.tsx"`.
This makes JSX/TSX components behave identically to SFCs in the
component tree panel.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two follow-up fixes for JSX/TSX component support:

1. Open in Editor did nothing when clicking the icon (devtools-kit)
   When the Vite plugin is active, __VUE_INSPECTOR__ is already set up with
   the correct launch-editor-middleware. The chrome-extension branch was
   bypassing it and falling back to a raw fetch that often failed silently.
   Now __VUE_INSPECTOR__ is preferred whenever vitePluginDetected is true,
   regardless of the devtools host. The fetch fallback is kept for cases where
   no Vite plugin is present, with a clearer console error message.

2. Plain function/arrow TSX components had no file icon (vite)
   The previous __hmrId piggyback only worked for defineComponent-based
   components. Plain exports like `export function HomeKpiGrid()` don't get
   __hmrId from @vitejs/plugin-vue-jsx. Added a second injection that derives
   the component name from the file name (PascalCase convention) and injects
   __file on it as a safe guard expression.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@NikhilVerma
Copy link
Copy Markdown
Author

Closing to reopen from a clean branch — follow-up open-in-editor work that was pushed to this branch is unverified and belongs in a separate PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant