Maldiligentaj ŝarĝaj moduloj en Svelte

Kiel importi vian komponenton laŭpeto

Dinamika importo en Svelte

Dum kodado en Svelte, vi eble havas la postulon nur ŝarĝi komponantojn laŭpeto, kiam ili efektive bezonas. React solvis ĉi tiun problemon sufiĉe majstre per ĝia "Suspenso"-komponento. Se vi volas atingi ion similan en Svelte, mi havas bonan novaĵon por vi.

Svelte "Suspenso" sen suspenso

Esence kio necesas estas uzi la enkonstruitan mekanismon de Svelte por atendi nesinkronajn funkciovokojn en la komponanto mem. La sekva simpla ekzemplo montras kion mi volas diri per tio.

<script>
  // Dummy function, just so that we
  // have some async stuff.
	async function getData() {
		await new Promise(res => setTimeout(res, 1000));
		return { key: "value" };
	}
</script>

{#await getData()}
	<p>Fetching data...</p>
{:then res}
	<p>Accessing data: "key": "{res.key}"</p>
{:catch error}
	<p style="color: red">{error.message}</p>
{/await}

Kiel vi povas vidi, ni simple atendas la revenan valoron de la funkcio kaj poste uzas ĝin en nia UI. La sama tekniko povas esti uzata por importi tutajn modulojn.

Dinamika importo kun Svelte

Uzante la dinamikan "importon", disponeblan en ES6, ni povas skribi simplan maldiligentan komponan importon.

//
// Live demo:
// https://svelte.dev/repl/b7551180977d4e738b07d428f3172d5e?version=3.46.4
//

//
// App.svelte
// 

<h1>App title</h1>

{#await import("./Content.svelte") then Module}
	<Module.default subtitle="Subtilte as prop" />
{/await}
//
// Content.svelte
//

<script>
	export let subtitle;
</script>

<article>
  <h2>
		Content title
	</h2>
	<h3>
		{subtitle}
	</h3>
	<p>
		Content body.
	</p>
</article>

Konstruante sur ĉi tiu scio, ni nun kapablas maldiligente ŝarĝi ajnan komponanton. Praktika ekzemplo, kiun mi efektive uzas por spikze.club, estas efektivigo de ununura "Ikono"-komponento, kiu ŝarĝas la specifan ikonon laŭpeto.

<!--
  Source: https://carbon-icons-svelte.onrender.com/
-->
<script lang="ts">
  // Using a link so that 'clsx' can eliminate
  // all other variant compared to an enum, which
  // should lead to a smaller size at runtime.
  export let variant: "internal-link" | "external-link" | "section-link" | "close" | "add-circle";
  let cn: string = undefined;
  export { cn as class };
</script>

{#if variant === "external-link"}
  {#await import("carbon-icons-svelte/lib/ArrowUpRight20") then Icon}
    <Icon.default class={cn} />
  {/await}
{/if}

{#if variant === "internal-link"}
  {#await import("carbon-icons-svelte/lib/ArrowRight20") then Icon}
    <Icon.default class={cn} />
  {/await}
{/if}

{#if variant === "section-link"}
  {#await import("carbon-icons-svelte/lib/ArrowDown20") then Icon}
    <Icon.default class={cn} />
  {/await}
{/if}

{#if variant === "close"}
  {#await import("carbon-icons-svelte/lib/Close20") then Icon}
    <Icon.default class={cn} />
  {/await}
{/if}

{#if variant === "add-circle"}
  {#await import("carbon-icons-svelte/lib/AddAlt20") then Icon}
    <Icon.default class={cn} />
  {/await}
{/if}

Envolvi

Vi vidis kiel uzi la dinamikan importadon de ES6 por simple importi ajnajn datumojn laŭ postulo. Ĉar ĉi tio validas por ambaŭ viaj komponantoj kaj ankaŭ por triaj bibliotekoj, nenio malhelpas vin grimpi vian sekvan Svelte-apon.