Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: ensure tree-shaken if blocks correctly hydrate #14589

Closed
wants to merge 3 commits into from

Conversation

trueadm
Copy link
Contributor

@trueadm trueadm commented Dec 6, 2024

Fixes #14588. We need to ensure we move the hydration node when the if block basically all gets tree-shaken away. Unfortunately, I found no way to test this as this relies on Rollup treeshaking away parts of the bundle and runtime.

Copy link

changeset-bot bot commented Dec 6, 2024

🦋 Changeset detected

Latest commit: 063ce36

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
svelte Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Contributor

github-actions bot commented Dec 6, 2024

Playground

pnpm add https://pkg.pr.new/svelte@14589

@Rich-Harris
Copy link
Member

Not sure I understand how treeshaking can affect the behaviour?

@trueadm
Copy link
Contributor Author

trueadm commented Dec 6, 2024

Not sure I understand how treeshaking can affect the behaviour?

Rollup is being super smart here, but it see's that the fn passed to $.if is empty, so it removes the function entirely. It then removes all the logic inside $.if relating to creation of the branches because of it, meaning we never move the hydration node.

Ending up with this:

function if_block(node, fn, elseif = false) {
  if (hydrating) {
    hydrate_next();
  }
  var anchor = node;
  var condition = null;
  var flags = elseif ? EFFECT_TRANSPARENT : 0;
  var has_branch = false;
  const update_branch = (new_condition, fn2) => {
    if (condition === (condition = new_condition)) return;
    let mismatch = false;
    if (hydrating) {
      const is_else = (
        /** @type {Comment} */
        anchor.data === HYDRATION_START_ELSE
      );
      if (condition === is_else) {
        anchor = traverse_nodes(true);
        set_hydrate_node(anchor);
        set_hydrating(false);
        mismatch = true;
      }
    }
    if (mismatch) {
      set_hydrating(true);
    }
  };
  block(() => {
    has_branch = false;
    if (!has_branch) {
      update_branch(null);
    }
  }, flags);
  if (hydrating) {
    anchor = hydrate_node;
  }
}

@Rich-Harris
Copy link
Member

preview: https://svelte-dev-git-preview-svelte-14589-svelte.vercel.app/

this is an automated message

@Rich-Harris
Copy link
Member

If the behaviour is different with treeshaking vs without then it must be a bug in Rollup, surely?

It's suspicious that we're calling update_branch(null) when condition is already null — means we're exiting early without ever hitting the if (hydrating) block. Could it be that we just need to do var condition = UNINITIALIZED?

@Rich-Harris
Copy link
Member

(though I don't really understand why that wouldn't show up in our test suite already...)

@trueadm
Copy link
Contributor Author

trueadm commented Dec 6, 2024

If the behaviour is different with treeshaking vs without then it must be a bug in Rollup, surely?

I thought that at first, but it's not because the entire block gets tree shaken, including the bit that does the hydration of the template – so we just need to ensure we move the hydration node accordingly.

@Rich-Harris
Copy link
Member

Reproduced the bug locally in the sandbox, which confirms that it's nothing to do with treeshaking, which is a relief because that would have indicated a very serious bug in Rollup.

The answer is quite simple — per #14589 (comment), we just need to do var condition = UNINITIALIZED and then coerce condition to a boolean when checking for a hydration mismatch. Opened #14597

@trueadm trueadm closed this Dec 6, 2024
@trueadm trueadm deleted the fix-hydration-if branch December 6, 2024 21:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Hydration error from regression when updating Svelte from 5.6.1 to 5.6.2
2 participants