AlexxNB / tinro

Highly declarative, tiny, dependency free router for Svelte's web applications.
MIT License
673 stars 30 forks source link

Promise and lazy routes... #1

Closed frederikhors closed 4 years ago

frederikhors commented 4 years ago

Amazing router! Congratulations!

Looking at yrv router (a good router!) we can see two ways of importing routes:

<Router>
  <Route exact path="/promise" component={import('path/to/other-component.svelte')}/>
  <Route exact path="/lazy" component={() => import('path/to/another-component.svelte')}/>
</Router>

The promise way I think is amazing because I can have a lot of routes and maybe I just need to load immediately just the one I need and after that in background start downloading others.

Can we do the same with tinro?

AlexxNB commented 4 years ago

Thanks =) I'll look for a way of minimal implementation of this. Module size is priority.

AlexxNB commented 4 years ago

Thinked about it. I'll not add this feature in the Tinro. Three reasons:

  1. It is not wide used feature
  2. It will increase Tinro package size
  3. Don't want use attribute like component={} because it is not so declarative as I want to see in Tinro.

Point of the Tinro is not in reproducing all functions of other routers(like 'yrv'), it has its own way.

But, you may easy use lazy-loaded components in Tinro right now:

<!-- App.svelte-->
<script>
    import {Route} from 'tinro';
    const lazyComponent = () => import('./Child.svelte'); // Just any common comonent
</script>

<Route path="/lazy">
    {#await lazyComponent()}
       Loading component...
    {:then Cmp}
       <svelte:component this={Cmp.default} />
    {/await}
</Route>

If you will use many lazy loading routes, you may create adaptor component where will be the part with {#await...} block;

See both cases in my example: https://ru.svelte.dev/repl/c41f454052594e3cbdf045ec71df75f6?version=3.21.0

frederikhors commented 4 years ago

It makes sense. Thanks. I'll try.

frederikhors commented 4 years ago

I tried this.

It works with ( )=> import() but it's really useful also to have routes with import() directly for pre-loading when I'm navigating other routes.

Is there a way to do it?

I can use the same code of you but it doesn't work because the <Lazy/> component is not evaluated if I not enter the relative <Route/>.

Did I explain my problem well?

AlexxNB commented 4 years ago

Little change in Lazyloader.svelte: Replace {#await cmp()} by {#await cmp.then ? cmp : cmp()} and you will be able to use either import or functions as cmp property.

Just load imports in variables in root file if you want to do preloading. Then use this variables for cmp property. Or just use <Lazylaoder cmp={import('./Something.svelte')}/> and components will be downloaded when current component will be mounted.

frederikhors commented 4 years ago

It works beautifully!