Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is a POC of migrating a small but more involved codebase to Svelte 5.
Notes
$derived.fn
a couple of times because of big derivations (ex:Folder.svelte
)$effect.pre
to run on the server, too, when converting some$:
statements that were not reactive assignments$derived
and$effect
is very helpful to understand better what kind of code I'm dealing with$props()
is the most tedious one (but also the easiest to automigrate)Menu.svelte
$state
" warning was very helpful in converting the right variables / not forgetting itwritable
there was a fixed contract making you think less about this because the container was already there. I ended up moving most separatewritable
s into one big$state
object because I don't have the "how to encapsulate it" problem then. This feels natural for state that belongs together but for primitive state you always have to think a bit how to do it. Usage-wise it didn't feel much different to stores, although doingx.set(newValue)
feels a bit nicer compared tocontainer.x = newValue
, which feels hacky because you're mutating stuff all over. That could just be me though, and in a certain way it might even be good because the hackyness of modifying stuff from everywhere without hiding it behind a proper method that changes things is more obvious that way - though it isn't as easy to forbid writing to the state because there's no way to mark something as readonly for the outside but have it be regular$state
within the same scope.e.detail.theName
to know what you're dealing with which can now be simplified to justtheName
). In one case I had to add$props()
because of event forwarding, which felt a bit more boilerplatey to write but afterwards it's much clearer what the component's in/outputs are because I can just scan for the$props()
rune. In that instance I also had to add thechildren
prop because it was receiving<slot />
content which was a bit confusing for a moment, maybe language tools can make it more clear what's going on there. Speaking of: I found the syntax highlighting to be worse, we should maybe highlight the attributes starting withon
differently, and we definetly should add semantic highlighting to them.Overall the migration was pretty straightforward, with a few gotchas which depending on your app could happen more or less frequently. The new code reads better overall to me, though not really much has changed, especially in the template (which is a good thing I'd say!)
Bugs
afterNavigate
doesnt fire initially, becauseonMount
is async now (result: editor doesn't show code contents for initial load); we need to callflushState()
in the backwards compatibility wrapper or in SvelteKitbind:this
triggers an update that is flushed in the next tick, in Svelte 5 it's synchronous. This results in one update in Svelte 4 with height/width set but two updates in Svelte 5 with the first having no width/height set yet, resulting in a too low calculation and therefore rendering the editor too small. I don't think we can fix this in Svelte 5 due to the timings, so the fix needs to happen in SvelteSplitPane (arguably it revealed a proper bug in the library)$state
instead of awritable
, I don't know why. It's proxied state, so its parts should be reactive