diff --git a/.changeset/forty-snakes-lay.md b/.changeset/forty-snakes-lay.md new file mode 100644 index 0000000000..6cb4c2d761 --- /dev/null +++ b/.changeset/forty-snakes-lay.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +feat: migrate reassigned deriveds to `$derived` diff --git a/packages/svelte/src/compiler/migrate/index.js b/packages/svelte/src/compiler/migrate/index.js index 7f26d0d010..b336ebb2b8 100644 --- a/packages/svelte/src/compiler/migrate/index.js +++ b/packages/svelte/src/compiler/migrate/index.js @@ -19,6 +19,7 @@ import { migrate_svelte_ignore } from '../utils/extract_svelte_ignore.js'; import { validate_component_options } from '../validate-options.js'; import { is_reserved, is_svg, is_void } from '../../utils.js'; import { regex_is_valid_identifier } from '../phases/patterns.js'; +import { VERSION } from 'svelte/compiler'; const regex_style_tags = /(]+>)([\S\s]*?)(<\/style>)/g; const style_placeholder = '/*$$__STYLE_CONTENT__$$*/'; @@ -113,6 +114,16 @@ function find_closing_parenthesis(start, code) { return end; } +function check_support_writable_deriveds() { + const [major, minor, patch] = VERSION.split('.'); + + if (+major < 5) return false; + if (+minor < 25) return false; + return true; +} + +const support_writable_derived = check_support_writable_deriveds(); + /** * Does a best-effort migration of Svelte code towards using runes, event attributes and render tags. * May throw an error if the code is too complex to migrate automatically. @@ -952,7 +963,11 @@ const instance_script = { const reassigned_bindings = bindings.filter((b) => b?.reassigned); if ( - reassigned_bindings.length === 0 && + // on version 5.25.0 deriveds are writable so we can use them even if + // reassigned (but if the right side is a literal we want to use `$state`) + (support_writable_derived + ? node.body.expression.right.type !== 'Literal' + : reassigned_bindings.length === 0) && !bindings.some((b) => b?.kind === 'store_sub') && node.body.expression.left.type !== 'MemberExpression' ) { diff --git a/packages/svelte/tests/migrate/samples/reassigned-deriveds/input.svelte b/packages/svelte/tests/migrate/samples/reassigned-deriveds/input.svelte new file mode 100644 index 0000000000..024f719fb9 --- /dev/null +++ b/packages/svelte/tests/migrate/samples/reassigned-deriveds/input.svelte @@ -0,0 +1,10 @@ + + + + + +{upper} \ No newline at end of file diff --git a/packages/svelte/tests/migrate/samples/reassigned-deriveds/output.svelte b/packages/svelte/tests/migrate/samples/reassigned-deriveds/output.svelte new file mode 100644 index 0000000000..0903299d95 --- /dev/null +++ b/packages/svelte/tests/migrate/samples/reassigned-deriveds/output.svelte @@ -0,0 +1,10 @@ + + + + + +{upper} \ No newline at end of file