diff --git a/.changeset/slow-kids-sparkle.md b/.changeset/slow-kids-sparkle.md new file mode 100644 index 0000000000..11f3ca69a8 --- /dev/null +++ b/.changeset/slow-kids-sparkle.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +fix: warn when `$props` rune not called diff --git a/packages/svelte/src/compiler/phases/2-analyze/validation.js b/packages/svelte/src/compiler/phases/2-analyze/validation.js index b43e5bea65..1790e073ec 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/validation.js +++ b/packages/svelte/src/compiler/phases/2-analyze/validation.js @@ -1002,7 +1002,12 @@ export const validation_runes = merge(validation, a11y_validators, { const init = node.init; const rune = get_rune(init, state.scope); - if (rune === null) return; + if (rune === null) { + if (init?.type === 'Identifier' && init.name === '$props' && !state.scope.get('props')) { + warn(state.analysis.warnings, node, path, 'invalid-props-declaration'); + } + return; + } const args = /** @type {import('estree').CallExpression} */ (init).arguments; diff --git a/packages/svelte/src/compiler/warnings.js b/packages/svelte/src/compiler/warnings.js index 2f8308e27f..20375bca76 100644 --- a/packages/svelte/src/compiler/warnings.js +++ b/packages/svelte/src/compiler/warnings.js @@ -27,7 +27,10 @@ const runes = { /** @param {string} name */ 'non-state-reference': (name) => `${name} is updated, but is not declared with $state(...). Changing its value will not correctly trigger updates.`, - 'derived-iife': () => `Use \`$derived.by(() => {...})\` instead of \`$derived((() => {...})());\`` + 'derived-iife': () => + `Use \`$derived.by(() => {...})\` instead of \`$derived((() => {...})());\``, + 'invalid-props-declaration': () => + `Component properties are declared using $props() in runes mode. Did you forget to call the function?` }; /** @satisfies {Warnings} */ diff --git a/packages/svelte/tests/validator/samples/runes-props-not-called/_config.js b/packages/svelte/tests/validator/samples/runes-props-not-called/_config.js new file mode 100644 index 0000000000..f47bee71df --- /dev/null +++ b/packages/svelte/tests/validator/samples/runes-props-not-called/_config.js @@ -0,0 +1,3 @@ +import { test } from '../../test'; + +export default test({}); diff --git a/packages/svelte/tests/validator/samples/runes-props-not-called/input.svelte b/packages/svelte/tests/validator/samples/runes-props-not-called/input.svelte new file mode 100644 index 0000000000..ec13f5ca10 --- /dev/null +++ b/packages/svelte/tests/validator/samples/runes-props-not-called/input.svelte @@ -0,0 +1,3 @@ + diff --git a/packages/svelte/tests/validator/samples/runes-props-not-called/warnings.json b/packages/svelte/tests/validator/samples/runes-props-not-called/warnings.json new file mode 100644 index 0000000000..d1900a3085 --- /dev/null +++ b/packages/svelte/tests/validator/samples/runes-props-not-called/warnings.json @@ -0,0 +1,14 @@ +[ + { + "code": "invalid-props-declaration", + "message": "Component properties are declared using $props() in runes mode. Did you forget to call the function?", + "start": { + "column": 5, + "line": 2 + }, + "end": { + "column": 19, + "line": 2 + } + } +]