Skip to content

Commit ed054fb

Browse files
committed
fix: ensure $effect.root is ignored on the server
Ignore the contents of the effect root, just return a noop where necessary fixes #12322
1 parent 5eff68f commit ed054fb

File tree

7 files changed

+41
-8
lines changed

7 files changed

+41
-8
lines changed

.changeset/wicked-emus-drive.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: ensure `$effect.root` is ignored on the server

packages/svelte/src/compiler/phases/3-transform/server/transform-server.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -412,11 +412,8 @@ const global_visitors = {
412412
}
413413

414414
if (rune === '$effect.root') {
415-
const args = /** @type {import('estree').Expression[]} */ (
416-
node.arguments.map((arg) => context.visit(arg))
417-
);
418-
// Just call the function directly
419-
return b.call(args[0]);
415+
// ignore $effect.root() calls, just return a noop which mimics the cleanup function
416+
return b.arrow([], b.block([]));
420417
}
421418

422419
if (rune === '$state.snapshot') {

packages/svelte/tests/runtime-legacy/shared.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export interface RuntimeTest<Props extends Record<string, any> = Record<string,
6161
warnings: any[];
6262
hydrate: Function;
6363
}) => void | Promise<void>;
64-
test_ssr?: (args: { assert: Assert }) => void | Promise<void>;
64+
test_ssr?: (args: { logs: any[]; assert: Assert }) => void | Promise<void>;
6565
accessors?: boolean;
6666
immutable?: boolean;
6767
intro?: boolean;
@@ -285,6 +285,7 @@ async function run_test_variant(
285285

286286
if (config.test_ssr) {
287287
await config.test_ssr({
288+
logs,
288289
// @ts-expect-error
289290
assert: {
290291
...assert,
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { flushSync } from 'svelte';
2+
import { test } from '../../test';
3+
4+
export default test({
5+
html: '<button>cleanup</button>',
6+
7+
async test({ assert, target, logs }) {
8+
const btn = target.querySelector('button');
9+
10+
btn?.click();
11+
flushSync();
12+
13+
assert.deepEqual(logs, ['effect1', 'effect2']);
14+
},
15+
test_ssr({ assert, logs }) {
16+
assert.deepEqual(logs, []);
17+
}
18+
});
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<script>
2+
$effect.root(() => {
3+
console.log('effect1');
4+
});
5+
const cleanup = $effect.root(() => {
6+
console.log('effect2');
7+
});
8+
</script>
9+
10+
<button onclick={cleanup}>cleanup</button>

packages/svelte/tests/runtime-runes/samples/effect-root/_config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,8 @@ export default test({
2424
});
2525

2626
assert.deepEqual(logs, [0, 1, 'cleanup 1', 'cleanup 2']);
27+
},
28+
test_ssr({ assert, logs }) {
29+
assert.deepEqual(logs, []);
2730
}
2831
});

packages/svelte/tests/runtime-runes/samples/event-store-no-hoisting/main.svelte

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
66
function setStore() {
77
store = writable(0, () => {
8-
console.log('start');
9-
return () => console.log('stop');
8+
return () => {};
109
});
1110
}
1211
</script>

0 commit comments

Comments
 (0)