From 9b39410e30c86cb1d50e7107326921a53a494999 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 22 Jan 2025 14:20:21 -0500 Subject: [PATCH] fix: optimise || expressions in template --- .changeset/large-islands-cover.md | 5 ++++ .../client/visitors/shared/utils.js | 26 +++++++++---------- 2 files changed, 18 insertions(+), 13 deletions(-) create mode 100644 .changeset/large-islands-cover.md diff --git a/.changeset/large-islands-cover.md b/.changeset/large-islands-cover.md new file mode 100644 index 000000000000..969d2fc25404 --- /dev/null +++ b/.changeset/large-islands-cover.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: optimise || expressions in template diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/utils.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/utils.js index 4c286166650e..00634f229eeb 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/utils.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/utils.js @@ -118,22 +118,22 @@ export function build_template_chunk( // extra work in the template_effect (instead we do the work in set_text). return { value, has_state }; } else { - let expression = value; - // only add nullish coallescence if it hasn't been added already - if (value.type === 'LogicalExpression' && value.operator === '??') { - const { right } = value; - // `undefined` isn't a Literal (due to pre-ES5 shenanigans), so the only nullish literal is `null` - // however, you _can_ make a variable called `undefined` in a Svelte component, so we can't just treat it the same way - if (right.type !== 'Literal') { - expression = b.logical('??', value, b.literal('')); - } else if (right.value === null) { - // if they do something weird like `stuff ?? null`, replace `null` with empty string - value.right = b.literal(''); + // add `?? ''` where necessary (TODO optimise more cases) + if ( + value.type === 'LogicalExpression' && + value.right.type === 'Literal' && + (value.operator === '??' || value.operator === '||') + ) { + // `foo ?? null` -=> `foo ?? ''` + // otherwise leave the expression untouched + if (value.right.value === null) { + value = { ...value, right: b.literal('') }; } } else { - expression = b.logical('??', value, b.literal('')); + value = b.logical('??', value, b.literal('')); } - expressions.push(expression); + + expressions.push(value); } quasi = b.quasi('', i + 1 === values.length);