diff --git a/.changeset/quiet-rivers-melt.md b/.changeset/quiet-rivers-melt.md new file mode 100644 index 0000000000..7ce1b9b2d3 --- /dev/null +++ b/.changeset/quiet-rivers-melt.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: declare `let:` directives before `{@const}` declarations on slotted elements diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js index 0579d80b74..1e6230a1f6 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js @@ -201,8 +201,8 @@ export function RegularElement(node, context) { } } - // Let bindings first, they can be used on attributes - context.state.init.push(...lets); + // Let bindings first, they can be used on attributes and `{@const}` declarations + context.state.let_directives.push(...lets); const node_id = context.state.node; diff --git a/packages/svelte/tests/runtime-legacy/samples/let-directive-and-const-tag-slotted/Nested.svelte b/packages/svelte/tests/runtime-legacy/samples/let-directive-and-const-tag-slotted/Nested.svelte new file mode 100644 index 0000000000..417e539554 --- /dev/null +++ b/packages/svelte/tests/runtime-legacy/samples/let-directive-and-const-tag-slotted/Nested.svelte @@ -0,0 +1,7 @@ + + +{#each things as thing} + +{/each} diff --git a/packages/svelte/tests/runtime-legacy/samples/let-directive-and-const-tag-slotted/_config.js b/packages/svelte/tests/runtime-legacy/samples/let-directive-and-const-tag-slotted/_config.js new file mode 100644 index 0000000000..bbbcd9ad12 --- /dev/null +++ b/packages/svelte/tests/runtime-legacy/samples/let-directive-and-const-tag-slotted/_config.js @@ -0,0 +1,15 @@ +import { test } from '../../test'; + +// `let:` directives on a slotted element must be declared before sibling `{@const}` +// declarations that capture them. In dev mode the `{@const}` derived is read eagerly, +// so a wrong declaration order throws "Cannot access '...' before initialization". +export default test({ + compileOptions: { + dev: true + }, + + html: ` +
1
+
2
+ ` +}); diff --git a/packages/svelte/tests/runtime-legacy/samples/let-directive-and-const-tag-slotted/main.svelte b/packages/svelte/tests/runtime-legacy/samples/let-directive-and-const-tag-slotted/main.svelte new file mode 100644 index 0000000000..e2530ef015 --- /dev/null +++ b/packages/svelte/tests/runtime-legacy/samples/let-directive-and-const-tag-slotted/main.svelte @@ -0,0 +1,10 @@ + + + +
+ {@const props = { thing }} + {props.thing} +
+