vite-plugin-vue icon indicating copy to clipboard operation
vite-plugin-vue copied to clipboard

HMR not working properly with named exports referencing variable declaration where the export comes first

Open c5n8 opened this issue 1 month ago • 1 comments

Related plugins

Describe the bug

// Foo.tsx
export { Foo }

const Foo = defineComponent(/* ... */)

This will also reload parent module, and can bubble up to page reload.

Reproduction

https://stackblitz.com/edit/vitejs-vite-hwbp51q3?file=src%2Fcomponents%2Ffoo.tsx

Steps to reproduce

No response

System Info

System:
  OS: Linux 5.0 undefined
  CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
  Memory: 0 Bytes / 0 Bytes
  Shell: 1.0 - /bin/jsh
Binaries:
  Node: 20.19.1 - /usr/local/bin/node
  Yarn: 1.22.19 - /usr/local/bin/yarn
  npm: 10.8.2 - /usr/local/bin/npm
  pnpm: 8.15.6 - /usr/local/bin/pnpm

Used Package Manager

npm

Logs

No response

Validations

c5n8 avatar Oct 26 '25 21:10 c5n8

This looks like a subtle HMR edge case tied to export timing. I flipped the declaration order:

const Foo = defineComponent(/* ... */) export { Foo }

With this structure, HMR behaves as expected—no parent reload. That suggests Vite’s graph may treat early exports as unresolved, triggering a reload cascade.

Hypothesis: When export { Foo } comes before const Foo = ..., Vite’s HMR boundary detection might encounter a temporal dead zone—especially with JSX transforms in play. Could be worth inspecting how plugin-vue-jsx handles named exports during transform.

Also curious if switching to export const Foo = ... or using default exports changes the behavior. Let me know if you'd like help isolating the transform step or mapping the reload cascade—happy to dig deeper.

wgrea avatar Oct 26 '25 21:10 wgrea