diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index e5681a3cebd9..709b829fcd46 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,11 @@ # svelte +## 5.27.3 + +### Patch Changes + +- fix: use function declaration for snippets in server output to avoid TDZ violation ([#15789](https://github.com/sveltejs/svelte/pull/15789)) + ## 5.27.2 ### Patch Changes diff --git a/packages/svelte/package.json b/packages/svelte/package.json index dc6c57b1a278..efead5604c3b 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -2,7 +2,7 @@ "name": "svelte", "description": "Cybernetically enhanced web apps", "license": "MIT", - "version": "5.27.2", + "version": "5.27.3", "type": "module", "types": "./types/index.d.ts", "engines": { diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/SnippetBlock.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/SnippetBlock.js index 5118679b3489..238485e665b6 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/SnippetBlock.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/SnippetBlock.js @@ -1,4 +1,4 @@ -/** @import { ArrowFunctionExpression, BlockStatement, CallExpression } from 'estree' */ +/** @import { BlockStatement } from 'estree' */ /** @import { AST } from '#compiler' */ /** @import { ComponentContext } from '../types.js' */ import { dev } from '../../../../state.js'; @@ -9,27 +9,21 @@ import * as b from '#compiler/builders'; * @param {ComponentContext} context */ export function SnippetBlock(node, context) { - const body = /** @type {BlockStatement} */ (context.visit(node.body)); + let fn = b.function_declaration( + node.expression, + [b.id('$$payload'), ...node.parameters], + /** @type {BlockStatement} */ (context.visit(node.body)) + ); - if (dev) { - body.body.unshift(b.stmt(b.call('$.validate_snippet_args', b.id('$$payload')))); - } + // @ts-expect-error - TODO remove this hack once $$render_inner for legacy bindings is gone + fn.___snippet = true; - /** @type {ArrowFunctionExpression | CallExpression} */ - let fn = b.arrow([b.id('$$payload'), ...node.parameters], body); + const statements = node.metadata.can_hoist ? context.state.hoisted : context.state.init; if (dev) { - fn = b.call('$.prevent_snippet_stringification', fn); + fn.body.body.unshift(b.stmt(b.call('$.validate_snippet_args', b.id('$$payload')))); + statements.push(b.stmt(b.call('$.prevent_snippet_stringification', fn.id))); } - const declaration = b.declaration('const', [b.declarator(node.expression, fn)]); - - // @ts-expect-error - TODO remove this hack once $$render_inner for legacy bindings is gone - fn.___snippet = true; - - if (node.metadata.can_hoist) { - context.state.hoisted.push(declaration); - } else { - context.state.init.push(declaration); - } + statements.push(fn); } diff --git a/packages/svelte/src/version.js b/packages/svelte/src/version.js index 62624e866cf2..c64eded9c4c8 100644 --- a/packages/svelte/src/version.js +++ b/packages/svelte/src/version.js @@ -4,5 +4,5 @@ * The current version, as set in package.json. * @type {string} */ -export const VERSION = '5.27.2'; +export const VERSION = '5.27.3'; export const PUBLIC_VERSION = '5'; diff --git a/packages/svelte/tests/runtime-runes/samples/snippet-access-in-script/_config.js b/packages/svelte/tests/runtime-runes/samples/snippet-access-in-script/_config.js new file mode 100644 index 000000000000..ed0ead960bdb --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/snippet-access-in-script/_config.js @@ -0,0 +1,7 @@ +import { test } from '../../test'; + +export default test({ + compileOptions: { + dev: true + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/snippet-access-in-script/fn.js b/packages/svelte/tests/runtime-runes/samples/snippet-access-in-script/fn.js new file mode 100644 index 000000000000..9e9a48c60cbe --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/snippet-access-in-script/fn.js @@ -0,0 +1,3 @@ +export function fn(snippet) { + return snippet; +} diff --git a/packages/svelte/tests/runtime-runes/samples/snippet-access-in-script/main.svelte b/packages/svelte/tests/runtime-runes/samples/snippet-access-in-script/main.svelte new file mode 100644 index 000000000000..cc73aa31db18 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/snippet-access-in-script/main.svelte @@ -0,0 +1,10 @@ + + +{#snippet test()} + {variable} +{/snippet} \ No newline at end of file diff --git a/packages/svelte/tests/runtime-runes/samples/snippet-invalid-call/_config.js b/packages/svelte/tests/runtime-runes/samples/snippet-invalid-call/_config.js new file mode 100644 index 000000000000..7e72fd751ab6 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/snippet-invalid-call/_config.js @@ -0,0 +1,9 @@ +import { test } from '../../test'; + +export default test({ + compileOptions: { + dev: true + }, + + error: 'invalid_snippet_arguments' +}); diff --git a/packages/svelte/tests/runtime-runes/samples/snippet-invalid-call/main.svelte b/packages/svelte/tests/runtime-runes/samples/snippet-invalid-call/main.svelte new file mode 100644 index 000000000000..3c47db3f96eb --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/snippet-invalid-call/main.svelte @@ -0,0 +1,7 @@ + + +{#snippet test()} +

hello

+{/snippet} diff --git a/packages/svelte/tests/snapshot/samples/bind-component-snippet/_expected/server/index.svelte.js b/packages/svelte/tests/snapshot/samples/bind-component-snippet/_expected/server/index.svelte.js index 04bfbf6ae47b..cadae2cf15c0 100644 --- a/packages/svelte/tests/snapshot/samples/bind-component-snippet/_expected/server/index.svelte.js +++ b/packages/svelte/tests/snapshot/samples/bind-component-snippet/_expected/server/index.svelte.js @@ -1,9 +1,9 @@ import * as $ from 'svelte/internal/server'; import TextInput from './Child.svelte'; -const snippet = ($$payload) => { +function snippet($$payload) { $$payload.out += `Something`; -}; +} export default function Bind_component_snippet($$payload) { let value = ''; pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy