How context="module" works in Svelte and Sapper?
Asked Answered
B

3

14

While I was using Sapper to build a project whenever I fetch data from server, preload function is declared inside of script context="module" like this below.

<script context="module">
  export async function preload(page) {
    return await this.fetch(`https://reqres.in/api/users?page=1`)
    .then(res1 => {
      return res1.json()
    }).then(res2 => {
      return { 
        notices: res2.data,
      }
    })
  }
</script>

According to the document

A <script> tag with a context="module" attribute runs once when the module first evaluates, rather than for each component instance. 

But what is the meaning of when the module first evaluates?

Does it mean that when a component first rendered? then isn't the same that declaring api fetch function inside of onMount lifecycle method just like the code below?

<script>
  onMount(async() => {
    const res = await fetch(`https://reqres.in/api/users?page=1`);
    const json = await res.json();
  })
</script>
Bolshevist answered 4/6, 2020 at 1:26 Comment(1)
AFAIK, unlike onMount which is called once per component instance, the context="module" script is only executed once.Librettist
N
29

Consider a regular JavaScript module that exports a class:

// Component.js

console.log('evaluating module');

export class Component {
  constructor() {
    console.log('instantiating component');
  }
}

If you import that module into your app, that code will run immediately:

import { Component } from './Component.js';

// "evaluating module" has already been logged. This will only happen once
// for the entire application, however many modules import Component.js

const component1 = new Component(); // logs "instantiating component"
const component2 = new Component(); // logs "instantiating component" again

Now we can put it in Svelte terms:

  • The 'evaluating module' code is what happens in the <script context="module">
  • The 'instantiating component' code is equivalent to what happens in the regular <script> tag
Nettle answered 6/6, 2020 at 23:12 Comment(0)
S
2

When using Sapper or SvelteKit (equivalent to Next.js in the react world), SSR components don't have access to the window object directly in the tag, so you need to wait until the component is "hydrated", or traditionally rendered. This means any libraries that use window, really anything that needs to run in the browser must be done through onMount

When using SSR, with tools such as SvelteKit, onMount() does not run on the server. Therefore, your client dependent code (such as local storage access) can be placed in onMount() where it will not throw a server error.

from https://www.reddit.com/r/sveltejs/comments/p5p386/trying_to_understand_script_vs_onmount/

Stallard answered 14/10, 2021 at 19:2 Comment(1)
You didn't answer how context='module' works.Collado
S
1

Yes, it is true, although there is a small difference: with context="module" the call is performed before creating the component.

Quoting from the official docs

it runs before the component is created

This is useful for cases like a list of products... you don't know which products to show, so you fetch the data and instantiate a product component for each of the item in the results.

Supersaturated answered 4/6, 2020 at 21:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.