parcel-transformer-svelte
parcel-transformer-svelte copied to clipboard
HMR duplicates module, doesn't replace
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:

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

I expect to see just one red box when I add text above the box.
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
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?
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 })
Even with that workaround, it is causing clicking a routed link to raise an exception until I refresh.
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.)
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()
})
}