fix: always pass original component to HMR wrapper (#12454)

When Vite calls `hot.accept`, it passes the wrapped component, which means we're passing the HMR wrapper along as the new component. Avoid that by maintaining a reference to the original component.
pull/12459/head
Simon H 1 year ago committed by GitHub
parent 1ce4cd5480
commit 436cc99740
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: always pass original component to HMR wrapper

@ -418,7 +418,7 @@ export function client_component(source, analysis, options) {
if (options.hmr) { if (options.hmr) {
const accept_fn_body = [ const accept_fn_body = [
b.stmt(b.call('$.set', b.id('s'), b.member(b.id('module'), b.id('default')))) b.stmt(b.call('$.set', b.id('s'), b.member(b.id('module.default'), b.id('original'))))
]; ];
if (analysis.css.hash) { if (analysis.css.hash) {
@ -440,8 +440,14 @@ export function client_component(source, analysis, options) {
const hmr = b.block([ const hmr = b.block([
b.const(b.id('s'), b.call('$.source', b.id(analysis.name))), b.const(b.id('s'), b.call('$.source', b.id(analysis.name))),
b.const(b.id('filename'), b.member(b.id(analysis.name), b.id('filename'))), b.const(b.id('filename'), b.member(b.id(analysis.name), b.id('filename'))),
b.const(b.id('$$original'), b.id(analysis.name)),
b.stmt(b.assignment('=', b.id(analysis.name), b.call('$.hmr', b.id('s')))), b.stmt(b.assignment('=', b.id(analysis.name), b.call('$.hmr', b.id('s')))),
b.stmt(b.assignment('=', b.member(b.id(analysis.name), b.id('filename')), b.id('filename'))), b.stmt(b.assignment('=', b.member(b.id(analysis.name), b.id('filename')), b.id('filename'))),
// Assign the original component to the wrapper so we can use it on hot reload patching,
// else we would call the HMR function two times
b.stmt(
b.assignment('=', b.member(b.id(analysis.name), b.id('original')), b.id('$$original'))
),
b.stmt(b.call('import.meta.hot.accept', b.arrow([b.id('module')], b.block(accept_fn_body)))) b.stmt(b.call('import.meta.hot.accept', b.arrow([b.id('module')], b.block(accept_fn_body))))
]); ]);

@ -12,12 +12,14 @@ function Hmr($$anchor) {
if (import.meta.hot) { if (import.meta.hot) {
const s = $.source(Hmr); const s = $.source(Hmr);
const filename = Hmr.filename; const filename = Hmr.filename;
const $$original = Hmr;
Hmr = $.hmr(s); Hmr = $.hmr(s);
Hmr.filename = filename; Hmr.filename = filename;
Hmr.original = $$original;
import.meta.hot.accept((module) => { import.meta.hot.accept((module) => {
$.set(s, module.default); $.set(s, module.default.original);
}); });
} }

Loading…
Cancel
Save