Search code examples
javascriptelectronsvelterollup

Unloading Svelte app, the reloading with new code


The svelte app is built in the Electron back-end, using rollup and some plugins on run-time. Currently I have a interval that triggers build every few seconds but I am planning to watch files and trigger build on change. The build code is then sent through IPC to the renderer preload script.

In this script, the code is put inside .innerHTML of a inline script tag that is appended to the document body (with type module).

ok, so far everything works, I can see the app rendering.

But if I send another IPC call with a new build code, after I replace the innerHTML I still see the previous svelte app, same html, styles and everything!

So that means that just replacing the javascript doesn't trigger a reload. Is there a way to trigger it, maybe some svelte function call for full cleanup or something?


the preload script may give a better idea of how I have this set up:

let build;
const bundle = document.createElement("script");
bundle.type = 'module';
function refreshApp(){
  if(build){
    bundle.innerHTML = `${build.js} new App({ target: document.body })`;
  }
}

ipcRenderer.on('build', (e, js, css ) => {
  build = { js, css }; // css not needed
  refreshApp(); // script tag contents are updated, but not the actual Svelte app
});

document.addEventListener("DOMContentLoaded", () => {
  document.body.appendChild(bundle);
  refreshApp();
});

Solution

  • Ideally store the component in a global variable and $destroy it first, or render it to a dedicated element that can then just be removed (though this will not clean up everything, e.g. global event listeners added via <svelte:window>, so I don't recommend this.

    I also would fully replace the old <script> instead of trying to reuse it, don't know what the spec says about this but would not expect that to even work.