Skip to content

Svelte 5: only inject push/init/pop when necessary #11297

Closed
@Rich-Harris

Description

@Rich-Harris

Describe the problem

The Svelte 5 <h1>hello world</h1> component looks like this:

var root = $.template(`<h1>hello world</h1>`);

function App($$anchor, $$props) {
  $.push($$props, false);
  $.init();

  var h1 = root();

  $.append($$anchor, h1);
  $.pop();
}

The push and pop stuff is required to maintain the context stack for various reasons, and init is required if lifecycle functions (afterUpdate, beforeUpdate, onMount) are used.

Describe the proposed solution

A lot of the stuff on the component context object pertains to non-runes mode, and we could simplify it in runes mode. But we could also get rid of it altogether in a lot of cases. E.g. in runes mode, I'm pretty sure we can get rid of it if there are no exports and we can guarantee that we're not (indirectly) calling setContext. (The context object includes space for effects, but it's actually fine if they get attached to the parent context.)

This basically means that if a component contains a call/member expression that we can't guarantee is 'safe', we add the push/pop, but if not then we leave it out. Ideally the output above would look like this (note that the $$props parameter has also been removed):

var root = $.template(`<h1>hello world</h1>`);

function App($$anchor) {
  $.append($$anchor, root());
}

Importance

nice to have

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