fix: use safe-equals comparison for `@const` tags in legacy mode (#10606)

fixes #10600
pull/10608/head
Simon H 2 years ago committed by GitHub
parent c10337cfb2
commit db0b802fc2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
"svelte": patch
---
fix: use safe-equals comparison for `@const` tags in legacy mode

@ -1793,7 +1793,8 @@ export const template_visitors = {
b.const(
declaration.id,
b.call(
'$.derived',
// In runes mode, we want things to be fine-grained - but not in legacy mode
state.options.runes ? '$.derived' : '$.derived_safe_equal',
b.thunk(/** @type {import('estree').Expression} */ (visit(declaration.init)))
)
)
@ -1822,7 +1823,10 @@ export const template_visitors = {
])
);
state.init.push(b.const(tmp, b.call('$.derived', fn)));
state.init.push(
// In runes mode, we want things to be fine-grained - but not in legacy mode
b.const(tmp, b.call(state.options.runes ? '$.derived' : '$.derived_safe_equal', fn))
);
for (const node of identifiers) {
const binding = /** @type {import('#compiler').Binding} */ (state.scope.get(node.name));

@ -0,0 +1,29 @@
import { tick } from 'svelte';
import { test } from '../../test';
// Test ensures that the `const` tag is coarse-grained in legacy mode (i.e. always fires an update when the array changes)
export default test({
html: `
<button>Show</button>
<p>0</p>
<p>1</p>
<p>2</p>
<p>3</p>
`,
async test({ target, assert }) {
const btn = target.querySelector('button');
btn?.click();
await tick();
assert.htmlEqual(
target.innerHTML,
`
<button>Show</button>
<p>0 show (v_item) show (item)</p>
<p>1</p>
<p>2 show (v_item) show (item)</p>
<p>3</p>
`
);
}
});

@ -0,0 +1,21 @@
<script>
export let items = {0:{clicked:false},length:4};
</script>
<button on:click={()=>{
items[0].clicked=true;
items[2]={clicked:true};
}}>Show</button>
{#each items as item, i}
{@const v_item=item}
<p>
{i}
{#if v_item?.clicked}
show (v_item)
{/if}
{#if item?.clicked}
show (item)
{/if}
</p>
{/each}
Loading…
Cancel
Save