Skip to content

Commit 33d118f

Browse files
feat: migrate reassigned deriveds to $derived (#15581)
1 parent c1ae895 commit 33d118f

File tree

4 files changed

+41
-1
lines changed

4 files changed

+41
-1
lines changed

.changeset/forty-snakes-lay.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
feat: migrate reassigned deriveds to `$derived`

packages/svelte/src/compiler/migrate/index.js

+16-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { migrate_svelte_ignore } from '../utils/extract_svelte_ignore.js';
1919
import { validate_component_options } from '../validate-options.js';
2020
import { is_reserved, is_svg, is_void } from '../../utils.js';
2121
import { regex_is_valid_identifier } from '../phases/patterns.js';
22+
import { VERSION } from 'svelte/compiler';
2223

2324
const regex_style_tags = /(<style[^>]+>)([\S\s]*?)(<\/style>)/g;
2425
const style_placeholder = '/*$$__STYLE_CONTENT__$$*/';
@@ -113,6 +114,16 @@ function find_closing_parenthesis(start, code) {
113114
return end;
114115
}
115116

117+
function check_support_writable_deriveds() {
118+
const [major, minor, patch] = VERSION.split('.');
119+
120+
if (+major < 5) return false;
121+
if (+minor < 25) return false;
122+
return true;
123+
}
124+
125+
const support_writable_derived = check_support_writable_deriveds();
126+
116127
/**
117128
* Does a best-effort migration of Svelte code towards using runes, event attributes and render tags.
118129
* May throw an error if the code is too complex to migrate automatically.
@@ -952,7 +963,11 @@ const instance_script = {
952963
const reassigned_bindings = bindings.filter((b) => b?.reassigned);
953964

954965
if (
955-
reassigned_bindings.length === 0 &&
966+
// on version 5.25.0 deriveds are writable so we can use them even if
967+
// reassigned (but if the right side is a literal we want to use `$state`)
968+
(support_writable_derived
969+
? node.body.expression.right.type !== 'Literal'
970+
: reassigned_bindings.length === 0) &&
956971
!bindings.some((b) => b?.kind === 'store_sub') &&
957972
node.body.expression.left.type !== 'MemberExpression'
958973
) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<script>
2+
let name = 'world';
3+
4+
$: upper = name.toUpperCase();
5+
</script>
6+
7+
<input bind:value={name} />
8+
<input bind:value={upper} />
9+
10+
{upper}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<script>
2+
let name = $state('world');
3+
4+
let upper = $derived(name.toUpperCase());
5+
</script>
6+
7+
<input bind:value={name} />
8+
<input bind:value={upper} />
9+
10+
{upper}

0 commit comments

Comments
 (0)