Search code examples
sveltesapper

How to generate separate js files when using [slug].svelte


I am using sapper to build a site that consists of many sub-pages that each use a different svelte component (with svg visualizations) and I plan to export it as a static site. Right now I am using a [slug].svelte file to get easy routing for the sub-pages.

My problem is that when I export the site, it generates one single huge [slug]....js file that seems to contain all the data for the visualizations of the sub-pages. Is there a way to get smaller/single js files for each sub-page when using [slug].svelte?

It seems I could just make my routes manually by making a folder for each sub-page and that way generate separate js files. Maybe the problem is that I am importing all the components in a single _select.svelte file to select the right svelte component for each sub-page. I was trying to import the components dynamically in hoping that this would generate a different js file for each sub-page, but then the static site generation won't work. I am probably doing something horribly wrong here...

Thanks for any hints!


Solution

  • Code-split entry points are created in two cases:

    • A .svelte or .js file is being treated as a route (as in [slug].svelte)
    • A dynamic import is used

    It sounds like you want the second option:

    <script>
      const imports = {
        a: () => import('./A.svelte'),
        b: () => import('./B.svelte'),
        c: () => import('./C.svelte')
      };
    
      export let component = 'a';
    </script>
    
    {#await imports[component]() then module}
      <svelte:component this={module.default}/>
    {/await}
    

    Demo here.

    Note that you have to spell out all the different import(...) possibilities — you can't do this sort of thing...

    <script>
      const imports = {
        a: './A.svelte',
        b: './B.svelte',
        c: './C.svelte'
      };
    
      export let component = 'a';
      $: promise = import(imports[component]);
    </script>
    
    {#await promise then module}
      <svelte:component this={module.default}/>
    {/await}
    

    ...because the bundler needs to be able to 'see' which files are dynamically imported when the app is built.