diff --git a/.changeset/lucky-knives-crash.md b/.changeset/lucky-knives-crash.md new file mode 100644 index 000000000000..b3506ecc4f71 --- /dev/null +++ b/.changeset/lucky-knives-crash.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: handle destructured primitive literals diff --git a/packages/playground/README.md b/packages/playground/README.md index 6ac0393720cc..e86c6b2da034 100644 --- a/packages/playground/README.md +++ b/packages/playground/README.md @@ -4,4 +4,6 @@ To prevent any changes you make in this directory from being accidentally commit If you would actually like to make some changes to the files here for everyone then run `git update-index --no-skip-worktree ./**/*.*` before committing. -If you're using VS Code, you can use the "Playground: Full" launch configuration to run the playground and attach the debugger to both the compiler and the browser. +If you're using VS Code, you can use the "Playground: Full" launch configuration to run the playground and attach the debugger to both the compiler and the browser. This will SSR the component and then also hydrate it on the client side using rollup to bundle any other imports. + +You can also just compile the `App.svelte` file by running `node compile.js` if you'd like to check some compiler behaviour in isolation. diff --git a/packages/playground/compile.js b/packages/playground/compile.js new file mode 100644 index 000000000000..8b6dac9f1a7f --- /dev/null +++ b/packages/playground/compile.js @@ -0,0 +1,6 @@ +import { readFileSync } from 'node:fs'; +import { compile } from '../svelte/src/compiler/index.js'; + +const code = readFileSync('src/App.svelte', 'utf8'); + +console.log(compile(code)); diff --git a/packages/svelte/src/compiler/compile/Component.js b/packages/svelte/src/compiler/compile/Component.js index 384bf067264c..06e849fe13b8 100644 --- a/packages/svelte/src/compiler/compile/Component.js +++ b/packages/svelte/src/compiler/compile/Component.js @@ -1292,26 +1292,22 @@ export default class Component { // everything except const values can be changed by e.g. svelte devtools // which means we can't hoist it if (node.kind !== 'const' && this.compile_options.dev) return false; - const { name } = /** @type {import('estree').Identifier} */ (d.id); - const v = this.var_lookup.get(name); - if (v.reassigned) return false; - if (v.export_name) return false; - if (this.var_lookup.get(name).reassigned) return false; - if ( - this.vars.find( - /** @param {any} variable */ (variable) => variable.name === name && variable.module - ) - ) { - return false; + for (const name of extract_names(d.id)) { + const v = this.var_lookup.get(name); + if (v.reassigned) return false; + if (v.export_name) return false; + + if (this.vars.find((variable) => variable.name === name && variable.module)) { + return false; + } } return true; }); if (all_hoistable) { node.declarations.forEach((d) => { - const variable = this.var_lookup.get( - /** @type {import('estree').Identifier} */ (d.id).name - ); - variable.hoistable = true; + for (const name of extract_names(d.id)) { + this.var_lookup.get(name).hoistable = true; + } }); hoistable_nodes.add(node); body.splice(i--, 1); diff --git a/packages/svelte/test/js/samples/hoisted-const/expected.js b/packages/svelte/test/js/samples/hoisted-const/expected.js index 33005b121de5..48bdf1f28b20 100644 --- a/packages/svelte/test/js/samples/hoisted-const/expected.js +++ b/packages/svelte/test/js/samples/hoisted-const/expected.js @@ -15,7 +15,7 @@ function create_fragment(ctx) { return { c() { b = element("b"); - b.textContent = `${get_answer()}`; + b.textContent = `${get_answer()} ${length}`; }, m(target, anchor) { insert(target, b, anchor); @@ -32,6 +32,7 @@ function create_fragment(ctx) { } const ANSWER = 42; +const { length } = 'abc'; function get_answer() { return ANSWER; diff --git a/packages/svelte/test/js/samples/hoisted-const/input.svelte b/packages/svelte/test/js/samples/hoisted-const/input.svelte index d248a8315425..4553a1952e76 100644 --- a/packages/svelte/test/js/samples/hoisted-const/input.svelte +++ b/packages/svelte/test/js/samples/hoisted-const/input.svelte @@ -1,6 +1,7 @@ -{get_answer()} \ No newline at end of file +{get_answer()} {length} \ No newline at end of file