迁移系统是一个工具,它提供了将 Svelte 组件从 Svelte 4 的语法自动转换为 Svelte 5 的基于 rune 的语法的能力。它执行了关键语法更改的转换,例如将 export let 转换为 $props(),将 $: 转换为 $derived 或 $effect,将 on:event 转换为 onevent,以及将 <slot> 转换为 {@render ...}。此页面详细介绍了迁移系统的工作原理以及它执行的转换。
有关用户角度的实际迁移过程的信息,请参阅 Svelte 5 Migration Guide
迁移系统旨在帮助开发人员将其代码迁移到 Svelte 5 的 rune API,而无需手动重写所有组件。它执行“尽最大努力”迁移,这意味着虽然它可以成功转换许多常见模式,但某些复杂代码可能需要在之后手动调整。
来源: packages/svelte/src/compiler/migrate/index.js115-457
迁移过程包括几个不同的阶段
来源: packages/svelte/src/compiler/migrate/index.js115-457 packages/svelte/src/compiler/migrate/index.js27-113
迁移系统处理许多语法转换,以将 Svelte 4 代码转换为 Svelte 5 代码。
最显著的变化之一是将反应式声明转换为 runes。
| Svelte 4 | Svelte 5 | 备注 |
|---|---|---|
let count = 0; | let count = $state(0); | 顶层变量被转换为 state。 |
$: doubled = count * 2; | const doubled = $derived(count * 2); | 简单的反应式声明变为派生值。 |
$: { /* side effects */ } | $effect(() => { /* side effects */ }); | 具有副作用的反应式块变为 effects。 |
export let prop; | let { prop } = $props(); | Props 通过解构收集。 |
export let prop = 'default'; | let { prop = 'default' } = $props(); | 默认值被保留。 |
来源: packages/svelte/src/compiler/migrate/index.js482-1037
事件处理语法被完全转换。
| Svelte 4 | Svelte 5 | 备注 |
|---|---|---|
<button on:click={handler}> | <button onclick={handler}> | 事件指令成为常规属性。 |
<button on:click|preventDefault> | <button onclick={preventDefault(handler)}> | 事件修饰符通过辅助函数进行处理。 |
<button on:click> | <button {onclick}> | 事件转发变为属性转发。 |
来源: packages/svelte/src/compiler/migrate/index.js1053-1037
Slots 被转换为新的 snippet 系统。
| Svelte 4 | Svelte 5 | 备注 |
|---|---|---|
<slot /> | {@render children?.()} | 默认 slot 变为 children snippet 渲染。 |
<slot name="header" /> | {@render header?.()} | 命名 slot 变为命名 snippet。 |
<div slot="header">...</div> | {#snippet header()}..{/snippet} | Slot 用法变为 snippet 声明。 |
来源: packages/svelte/src/compiler/migrate/index.js1061-1071 packages/svelte/tests/migrate/samples/slots/output.svelte1-28
迁移系统还处理特定组件的转换。
来源: packages/svelte/src/compiler/migrate/index.js41-96 packages/svelte/src/compiler/migrate/index.js155-456
迁移系统还处理 CSS 转换,特别是关于全局选择器和伪选择器。
来源: packages/svelte/src/compiler/migrate/index.js41-96
并非所有代码都可以自动迁移。迁移系统会识别需要手动干预的情况,并添加适当的注释。
需要手动干预的常见场景
beforeUpdate 和 afterUpdate 生命周期钩子的组件。createEventDispatcher。来源: packages/svelte/src/compiler/migrate/index.js440-456
迁移系统使用了几个关键库和技术。
在迁移过程中,系统会跟踪各种信息。
来源: packages/svelte/src/compiler/migrate/index.js459-480
迁移系统使用 AST 访问器来转换代码。以下是关键访问器的概述:
instance_script 访问器处理组件脚本部分的转换。
let 转换为 $state 并提取 props。$: 语句转换为 $derived 或 $effect。来源: packages/svelte/src/compiler/migrate/index.js482-1037
template 访问器处理组件模板中的转换。
<svelte:self> 转换为导入组件。来源: packages/svelte/src/compiler/migrate/index.js1053-1071
来源: packages/svelte/src/compiler/migrate/index.js115-457 packages/svelte/src/compiler/migrate/index.js459-480
迁移系统处理了几个具有挑战性的场景。
对于 TypeScript 组件,系统会尝试保留类型信息。
对于具有大量 props 的组件,它会生成一个接口或 JSDoc 类型。
来源: packages/svelte/tests/migrate/samples/props-ts/output.svelte1-37 packages/svelte/tests/migrate/samples/jsdoc-with-comments/output.svelte1-57
系统通过将 JSDoc 注释转移到迁移后的代码来保留它们
来源: packages/svelte/tests/migrate/samples/jsdoc-with-comments/input.svelte1-52 packages/svelte/tests/migrate/samples/jsdoc-with-comments/output.svelte1-57
迁移系统通过创建适当的动态组件来处理 <svelte:component> 用法的转换
来源: packages/svelte/tests/migrate/samples/svelte-component/output.svelte1-243
迁移系统为将 Svelte 代码更新到新的 Svelte 5 语法提供了一个强大的工具。虽然它可以处理许多常见模式,但开发人员应审查迁移后的代码,并解决注释指示的任何迁移任务。该系统在自动化转换和保留代码的原始意图之间取得了平衡,使迁移过程更易于管理。