Skip to content

Feature Request: Treat $derived.by runes as if their functions are called immediately to avoid runtime errors in SSR #2818

@dimfeld

Description

@dimfeld

Description

Given the following example code:

// Typescript will complain about this one
const regularFunction = (() => {
  return value;
})()

// But not this
let derivedValue = $derived.by(() => value);

let value = 5;

derivedValue works fine on the client, but when compiling for SSR the $derived.by function is called immediately, which throws an error because value is not yet initialized. And so you get potential errors which are easy to miss if your testing isn't checking both server and client-side compiled code.

Proposed solution

Typescript is properly able to detect that regularFunction is improper because it is called immediately, but on the server derivedFunction is compiled to pretty much the same syntax.

Is there a way in the language tools to do the syntax transformation for $derived.by runes so that they are treated similarly?

Transforming to something like (() => value)(); might be sufficient.

Or more generally:
$derived.by(FUNCTION) transforms to (FUNCTION)();

Alternatives

This could be handled in the Svelte compiler:

  1. Some kind of hoisting of let variables above $derived runes but this feels like a bad idea since it changes JS hoisting rules and is a whole new surface area for bugs.
  2. It could raise a warning/error but it seems like it's not checking for most of the other "use before initialize" cases here so there's no precedent.

So I think the language tools are probably a better place for this.

Additional Information, eg. Screenshots

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions