From 426792492a7298fa15d0a5f2e654f233505ef459 Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Fri, 28 Jun 2024 18:11:27 +0100 Subject: [PATCH] fix: deconflict multiple snippets of the same name --- .changeset/witty-hornets-think.md | 5 +++ .../3-transform/client/visitors/template.js | 38 +++++++++++++------ .../samples/svelte-element/output.svelte | 2 +- .../samples/snippets/output.json | 4 +- .../samples/snippet-deconflict/_config.js | 24 ++++++++++++ .../samples/snippet-deconflict/main.svelte | 29 ++++++++++++++ .../_expected/client/index.svelte.js | 2 +- .../_expected/client/index.svelte.js | 2 +- 8 files changed, 90 insertions(+), 16 deletions(-) create mode 100644 .changeset/witty-hornets-think.md create mode 100644 packages/svelte/tests/runtime-runes/samples/snippet-deconflict/_config.js create mode 100644 packages/svelte/tests/runtime-runes/samples/snippet-deconflict/main.svelte diff --git a/.changeset/witty-hornets-think.md b/.changeset/witty-hornets-think.md new file mode 100644 index 0000000000..2d25b7f437 --- /dev/null +++ b/.changeset/witty-hornets-think.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: deconflict multiple snippets of the same name diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js index b28c73c4d8..d836e35bb4 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js @@ -1096,13 +1096,12 @@ function serialize_update(statement) { } /** - * - * @param {import('../types.js').ComponentClientTransformState} state + * @param {import('estree').Statement[]} update */ -function serialize_render_stmt(state) { - return state.update.length === 1 - ? serialize_update(state.update[0]) - : b.stmt(b.call('$.template_effect', b.thunk(b.block(state.update)))); +function serialize_render_stmt(update) { + return update.length === 1 + ? serialize_update(update[0]) + : b.stmt(b.call('$.template_effect', b.thunk(b.block(update)))); } /** @@ -1709,7 +1708,7 @@ export const template_visitors = { } if (state.update.length > 0) { - body.push(serialize_render_stmt(state)); + body.push(serialize_render_stmt(state.update)); } body.push(...state.after_update); @@ -2157,8 +2156,21 @@ export const template_visitors = { state.options.preserveComments ); + /** + * @type {import("estree").Statement[]} + */ + const init = []; + /** + * @type {never[]} + */ + const update = []; + /** + * @type {never[]} + */ + const after_update = []; + for (const node of hoisted) { - context.visit(node, state); + context.visit(node, { ...state, init, update, after_update }); } process_children( @@ -2171,9 +2183,13 @@ export const template_visitors = { : context.state.node ), true, - { ...context, state } + { ...context, state: { ...state, init, update, after_update } } ); + if (init.length !== 0 || update.length !== 0 || after_update.length !== 0) { + context.state.init.push(b.block([...init, serialize_render_stmt(update), ...after_update])); + } + if (has_direction_attribute) { // This fixes an issue with Chromium where updates to text content within an element // does not update the direction when set to auto. If we just re-assign the dir, this fixes it. @@ -2270,7 +2286,7 @@ export const template_visitors = { /** @type {import('estree').Statement[]} */ const inner = inner_context.state.init; if (inner_context.state.update.length > 0) { - inner.push(serialize_render_stmt(inner_context.state)); + inner.push(serialize_render_stmt(inner_context.state.update)); } inner.push(...inner_context.state.after_update); inner.push( @@ -2735,7 +2751,7 @@ export const template_visitors = { snippet = b.call('$.wrap_snippet', snippet, b.id(context.state.analysis.name)); } - const declaration = b.var(node.expression, snippet); + const declaration = b.const(node.expression, snippet); // Top-level snippets are hoisted so they can be referenced in the ` + + + +
+
+ {#snippet x(n)} +

{n}

+ {/snippet} + + {#each numbers as n} + {@render x(n)} + {/each} +
+ +
+ {#snippet x(n)} +

{n}

+ {/snippet} + + {#each numbers as n} + {@render x(n)} + {/each} +
+
diff --git a/packages/svelte/tests/snapshot/samples/bind-component-snippet/_expected/client/index.svelte.js b/packages/svelte/tests/snapshot/samples/bind-component-snippet/_expected/client/index.svelte.js index 0e193af12d..ba4352d57b 100644 --- a/packages/svelte/tests/snapshot/samples/bind-component-snippet/_expected/client/index.svelte.js +++ b/packages/svelte/tests/snapshot/samples/bind-component-snippet/_expected/client/index.svelte.js @@ -6,7 +6,7 @@ var root_1 = $.template(`Something`, 1); var root = $.template(` `, 1); export default function Bind_component_snippet($$anchor) { - var snippet = ($$anchor) => { + const snippet = ($$anchor) => { var fragment = root_1(); $.append($$anchor, fragment); diff --git a/packages/svelte/tests/snapshot/samples/state-proxy-literal/_expected/client/index.svelte.js b/packages/svelte/tests/snapshot/samples/state-proxy-literal/_expected/client/index.svelte.js index 7cb2415bf5..0f2d6f4200 100644 --- a/packages/svelte/tests/snapshot/samples/state-proxy-literal/_expected/client/index.svelte.js +++ b/packages/svelte/tests/snapshot/samples/state-proxy-literal/_expected/client/index.svelte.js @@ -30,4 +30,4 @@ export default function State_proxy_literal($$anchor) { $.append($$anchor, fragment); } -$.delegate(["click"]); +$.delegate(["click"]); \ No newline at end of file