svelte-routing icon indicating copy to clipboard operation
svelte-routing copied to clipboard

Router doesn't work when immutable compiler option is set to true

Open kevinrenskers opened this issue 4 years ago • 2 comments

I am working purely with immutable data in my Svelte app, so I figured I'd set immutable to true in my Rollup config.

plugins: [
  svelte({
    immutable: true,
    // the usual stuff

Sadly this router doesn't really work like that.

App.svelte

<script>
  import { Router, Route, links } from "svelte-routing";
</script>

<Router>
  <nav use:links>
    <a href="/">Home</a>
  </nav>
  <main>
    <Route path="/"><h1>Hello world</h1></Route>
  </main>
</Router>

When you visit this in the browser, you don't see the "Hello world" message until you click on the Home link. When you click the navigation link, the home component does show up. It's the same with any other routes, nested routes, etc. On first load, nothing is shown, until you use a link to go somewhere.

Is this maybe simply a matter of initializing the internal store with the initial URL first, something like that?

kevinrenskers avatar Apr 15 '20 19:04 kevinrenskers

Hi @kevinrenskers!

Thank you for reporting this. I had not considered that the immutability option would have any impact on the router. I will look into it and come back to you with my findings.

EmilTholin avatar May 19 '20 11:05 EmilTholin

Well, thanks for mentioning this! I thought I was going crazy there for a while. Since the issue is still open, here are some details about my scenario.

  • I hydrate an app component in a pre-rendered page. I noticed that no route seemed to match - my pre-rendered page contains correct content, but it is overwritten by an empty block when hydrating.
  • I inserted creative debug outputs in strategic places and found that this code in Router.svelte is only executed once:
  // This reactive statement will be run when the Router is created
  // when there are no Routes and then again the following tick, so it
  // will not find an active Route in SSR and in the browser it will only
  // pick an active Route after all Routes have been registered.
  $: {
    const bestMatch = pick($routes, $location.pathname);
    activeRoute.set(bestMatch);
  }

The one execution I see happens when $routes is still empty. When running in my dev environment, without the immutable compiler option, I see a second execution a bit later, when routes exist.

  • I just disabled immutable, and then everything works correctly. Since the reactive code should be triggered by changes to $routes, I suspect that the problem is in the various in-place updates to the route list that take place in the router code. At a glance I see push and splice.

I expect this could be fixed easily enough - if it can't, perhaps a warning in an obvious place would be a good idea!

oliversturm avatar Mar 24 '21 17:03 oliversturm