fix: use fine grained for template if the component is not explicitly in legacy mode

pull/16232/head
paoloricciuti 3 months ago
parent 2af7ba2156
commit 44bec4c8b1

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: use fine grained for template if the component is not explicitly in legacy mode

@ -431,6 +431,26 @@ export function analyze_component(root, source, options) {
template,
elements: [],
runes,
// if we are not in runes mode but we have no reserved references ($$props, $$restProps)
// and no `export let` we might be in a wannabe runes component that is using runes in an external
// module...we need to fallback to the runic behavior
maybe_runes:
!runes &&
// if they explicitly disabled runes, use the legacy behavior
options.runes !== false &&
!module.scope.references.keys().some((name) => ['$$props', '$$restProps'].includes(name)) &&
!instance.ast.body.some(
(node) =>
node.type === 'ExportNamedDeclaration' &&
((node.declaration &&
node.declaration.type === 'VariableDeclaration' &&
node.declaration.kind === 'let') ||
node.specifiers.some(
(specifier) =>
specifier.local.type === 'Identifier' &&
instance.scope.get(specifier.local.name)?.declaration_kind === 'let'
))
),
tracing: false,
classes: new Map(),
immutable: runes || options.immutable,

@ -370,7 +370,7 @@ export function validate_mutation(node, context, expression) {
export function build_expression(context, expression, metadata, state = context.state) {
const value = /** @type {Expression} */ (context.visit(expression, state));
if (context.state.analysis.runes) {
if (context.state.analysis.runes || context.state.analysis.maybe_runes) {
return value;
}

@ -51,6 +51,7 @@ export interface ComponentAnalysis extends Analysis {
/** Used for CSS pruning and scoping */
elements: Array<AST.RegularElement | AST.SvelteElement>;
runes: boolean;
maybe_runes: boolean;
tracing: boolean;
exports: Array<{ name: string; alias: string | null }>;
/** Whether the component uses `$$props` */

@ -0,0 +1,14 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
mode: ['client'],
async test({ assert, target }) {
const p = target.querySelector('p');
const btn = target.querySelector('button');
flushSync(() => {
btn?.click();
});
assert.equal(p?.innerHTML, '0');
}
});

@ -0,0 +1,8 @@
<svelte:options runes={false} />
<script>
import { get, set } from "./test.svelte.js";
</script>
<p>{get()}</p>
<button onclick={()=>set()}></button>

@ -0,0 +1,9 @@
let count = $state(0);
export function get() {
return count;
}
export function set() {
count++;
}

@ -0,0 +1,14 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
mode: ['client'],
async test({ assert, target }) {
const p = target.querySelector('p');
const btn = target.querySelector('button');
flushSync(() => {
btn?.click();
});
assert.equal(p?.innerHTML, '1');
}
});

@ -0,0 +1,9 @@
<script>
import { get, set } from "./test.svelte.js";
export const x = 42;
</script>
<p>{get()}</p>
<button onclick={()=>set()}></button>

@ -0,0 +1,9 @@
let count = $state(0);
export function get() {
return count;
}
export function set() {
count++;
}

@ -0,0 +1,14 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
mode: ['client'],
async test({ assert, target }) {
const p = target.querySelector('p');
const btn = target.querySelector('button');
flushSync(() => {
btn?.click();
});
assert.equal(p?.innerHTML, '1');
}
});

@ -0,0 +1,12 @@
<script>
import { get, set } from "./test.svelte.js";
let x = 42;
export { x };
</script>
{x}
<p>{get()}</p>
<button onclick={()=>set()}></button>

@ -0,0 +1,9 @@
let count = $state(0);
export function get() {
return count;
}
export function set() {
count++;
}

@ -0,0 +1,14 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
mode: ['client'],
async test({ assert, target }) {
const p = target.querySelector('p');
const btn = target.querySelector('button');
flushSync(() => {
btn?.click();
});
assert.equal(p?.innerHTML, '1');
}
});

@ -0,0 +1,7 @@
<script>
import { get, set } from "./test.svelte.js";
</script>
<p>{get()}</p>
<button onclick={()=>set()}></button>

@ -0,0 +1,9 @@
let count = $state(0);
export function get() {
return count;
}
export function set() {
count++;
}
Loading…
Cancel
Save