-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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 : reactivity bug with single script in svelte:head #13386
Conversation
|
For the fix, I force the |
I think we should add a test for this but i'm not sure JSDom will behave correctly but is worth trying. However i'm thinking...could a better and simpler solution be returning the cloned script from |
I tried that on the previous PR that I closed, and I think it's more verbose : https://github.com/sveltejs/svelte/pull/13385/files |
But if you are returning the right node why are you still heavily changing the logic inside |
You are right, I redid the code and it is much simpler. But in the main time I think I found another bug : I don't understand the export function template_with_script(content, flags) {
var first = true;
var fn = template(content, flags);
return () => {
if (hydrating) return fn();
var node = /** @type {Element | DocumentFragment} */ (fn());
if (first) {
first = false;
run_scripts(node);
}
return node;
};
} Why run_scripts() is only executed on the first template ? Finally I tried to do a test, without success. |
It's not on the first template, it's the first time the template is used. I think I saw some comments somewhere about why we don't want to re-run the scripts after the first time. I'm not at the desk now but you can try searching some PR to see if there was a discussion.
Yeah that's why I said JSdom could be tricky to work with in this case...if you search the codebase for JSDom there should be some comment but I can't remember if it was related to scripts |
I found the PR where the But I don't see any discussion about that... |
Tbf i think this was probably a bug...i think it all stemmed from the fact that initially the fragment was cached so script only ran once but i think we should probably remove it. But I would love for @dummdidumm or @Rich-Harris to confirm this. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will undo some of the other fixes (which sadly can't be really tested). I'm a bit surprised this issue isn't handled by the existing logic of waiting one micro task
That's exactly the bug: we are using I guess the fix is to move the cloning logic into |
There's other problems with the replacement logic after a tick I just realized: Svelte's walking mechanism will be finished by this time and so it will have a reference to an outdated script node. If you ever change a value of that script it won't work. |
Yeah exactly the bug. |
template_with_script()
is buggy when it contains only one<script>
element, because therun_scripts()
will clone and replace the scripts.There no problem when using a DocumentFragment because they are replaced immediately inside the fragment.
But with a single node the element cannot be replaced, and it's done later with queue_micro_task().
=> So the cloned script is put on the DOM, but
template_with_script()
will return the previous script element (so reactivity is broken).See #13378
Should I make a test for that ?
Svelte 5 rewrite
Please note that the Svelte codebase is currently being rewritten for Svelte 5. Changes should target Svelte 5, which lives on the default branch (
main
).If your PR concerns Svelte 4 (including updates to svelte.dev.docs), please ensure the base branch is
svelte-4
and notmain
.Before submitting the PR, please make sure you do the following
feat:
,fix:
,chore:
, ordocs:
.Tests and linting
pnpm test
and lint the project withpnpm lint