parcel-transformer-svelte icon indicating copy to clipboard operation
parcel-transformer-svelte copied to clipboard

HMR duplicates module, doesn't replace

Open canadaduane opened this issue 4 years ago • 6 comments

I'm seeing modified modules in the development server get appended instead of replaced. I believe the way Hot Module Reloading (HMR) should work is it should replace modified modules.

As an example of the problem, the red box test case app normally shows one red box:

image

But when I modify the source code to add the text "hi!" it does not replace the module, it appends it:

image

I expect to see just one red box when I add text above the box.

canadaduane avatar Sep 20 '20 03:09 canadaduane

I believe we may be missing a uniqueKey in the transformation output. The VueTransformer (as an example of another implementation of a Transformer) has such a key here:

https://github.com/parcel-bundler/parcel/blob/v2/packages/transformers/vue/src/VueTransformer.js#L462

canadaduane avatar Sep 20 '20 04:09 canadaduane

uniqueKey didn't seem to fix the issue. I'm also wondering if it's truly HMR, or if there is some other mechanism that reloads pages or modules?

canadaduane avatar Sep 20 '20 06:09 canadaduane

as workaround you can clean your app's target before init component:

import App from './App.svelte';

const target = document.getElementById('svelte-root')
target.innerHTML = ''
new App({ target })

orlov-vo avatar Sep 23 '20 21:09 orlov-vo

Even with that workaround, it is causing clicking a routed link to raise an exception until I refresh.

SmileyChris avatar Oct 08 '20 22:10 SmileyChris

I seem to be getting a huge memory leak here too -- each time the app is hot-reloaded, the memory consumption increases 1-fold. Something is definitely wrong...

(Edit: while the workaround suggested by @orlov-vo works to clear the target element before the modules are rendered, it doesn't seem to clear them from the runtime, hence the issue @SmileyChris notes above and the memory leakage.)

simonwiles avatar Oct 31 '20 06:10 simonwiles

You can also try to use HMR-API for component disposing

import App from './App.svelte';

const target = document.getElementById('svelte-root')
const app = new App({ target });

if (module.hot) {
    module.hot.dispose(() => {
        app.$destroy()
    })
}

orlov-vo avatar Jan 21 '21 12:01 orlov-vo