Svelte 深度知识
将此作为可能知识差距的索引。在规划和实现期间,根据官方的 Svelte MCP 验证相关 API。
验证日期:2026-11-01,针对 Svelte 5.57.3、SvelteKit 3.1.1 和 SvelteKit 2.70.3。
从已安装的版本开始
- 检查包的版本和 Vite 配置。根据已安装的 Kit 主版本和启用的实验性标志匹配指导。
- 调用 Svelte MCP 的
list-sections,然后通过get-documentation获取相关章节。MCP 和 svelte.dev 提供 Kit 3 的文档。对于 Kit 2 项目,从sveltejs/kit的version-2分支下的documentation/docs读取匹配的页面。 - 对于 Kit 3 项目和 Kit 2 → 3 迁移,阅读 Kit 3 参考。对于 Kit 2 项目,阅读 Kit 2 参考。
- 对新建或编辑的 Svelte 组件/模块运行
svelte-autofixer并解决适用的问题。使用项目的检查来集成和类型检查。
有关新 Svelte API、异步渲染、附件和编译器工具的示例,请阅读 Svelte 参考。
远程函数、边界和 await
对于采用实验性异步的新 SvelteKit 应用程序,首选直接使用 await 的远程函数来处理组件数据,并使用细粒度的边界来处理加载/错误 UI。根据必须在服务器上渲染的内容选择 svelte:boundary 的位置。
- 一起启用
experimental.remoteFunctions和compilerOptions.experimental.async。官方的远程函数设置需要这两个标志。 load、表单操作和+server路由仍然受支持,但不鼓励。除非任务包含迁移,否则遵循现有架构。.loading、.error和.current仍然是受支持的查询 API。直接await是首选的机制。- 在渲染和命令式上下文中使用
await query(args)。 {#await}仍然受支持但不鼓励,并且有其自己的 promise 状态行为。使用直接 await 和边界进行协调的异步渲染;当{#await}的行为符合任务时,保留它。
使用 MCP 章节 kit/remote-functions、svelte/await-expressions 和 svelte/svelte-boundary 进行验证。
异步渲染行为
- 组件级别的 await 在 Svelte 5.36 中引入;异步 SSR 在 5.39 中引入。await 在顶级脚本、
$derived和标记中受支持。 - Svelte 在异步工作解析时协调相关的 UI 更新。独立的模板 await 表达式并发运行。顺序的脚本 await 仍然会创建瀑布;在执行 await 结果之前开始独立工作。
- 边界的
pending片段在首次创建时出现。使用$effect.pending()处理该边界中的后续工作;其计数排除子边界。 - 在 SSR 期间,带有
pending的边界渲染占位符并跳过其内容。此类边界之外的 await 表达式在await render(...)完成之前解析。相应地放置初始 HTML 中所需的内容。此 API 尚未提供流式 SSR。 $state.eager(value)(在 5.41 中添加)在协调更新等待时提供即时反馈。将其用于用户反馈,例如活动导航指示器。tick()等待待处理的状态更改;settled()(在 5.36 中添加)也等待由此产生的异步工作和最终的 DOM 更新。
错误边界
<svelte:boundary>支持failed(error, reset)和onerror(error, reset)以处理渲染/效果失败。在其调用站点处理事件处理程序和分离的异步错误。- 自 Svelte 5.53 起,
failed片段还会在 SSR 期间捕获错误。在 SvelteKit 中,错误首先通过handleError,因此片段接收经过清理的App.Error。当失败的边界水合时,onerror运行。 - Kit 3 通过
handleError将渲染错误发送到最近的+error.svelte,后者充当边界。异步客户端handleError需要compilerOptions.experimental.async。Kit 2.54+ 需要experimental.handleRenderingErrors来实现相同的集成。 - 边界文档中较旧的“自 5.51 起”注释与已发布的更改日志冲突。将 5.53 用作引入版本,并在诊断 SSR/水合问题检查当前的补丁。
模板特性
声明标签,Svelte 5.56+
- 对于标记局部变量,首选
{let ...}和{const ...}。{@const}被记录为遗留特性,并且仍可用于较旧的项目。 - 普通声明初始化值。使用显式的 Runes 实现响应性:
{let count = $state(0)}和{const doubled = $derived(count * 2)}。 - 迁移响应的
{@const area = width * height}需要{const area = $derived(width * height)}。普通的{const area = width * height}不是响应式的。 - 声明在其元素/块内使用词法作用域,可以隐藏外部变量,并且应在使用之前声明。支持多个声明符。
附件
- 对于 Svelte 5.29+ 上的新元素集成,首选
{@attach ...}。从附件返回清理函数。 - 附件跟踪响应式读取,并在依赖项更改时重新运行。假值会禁用它们。避免通过子效果中的 getter 读取更改的选项来重复昂贵的设置。
- 组件包装器必须将附件的 prop 转发到目标元素。
createAttachmentKey()支持展开对象中的附件。 fromAction(action, () => argument)保留现有操作的行为。其第二个参数是一个 getter。此辅助函数在附件本身之后到达 5.32。
类、绑定和 HTML
- 自 5.16 起,
class接受嵌套数组和对象。自 5.19 起,来自svelte/elements的ClassValue可用于包装器 props。 - 自 5.9 起,函数绑定使用
bind:value={get, set}。对于只读绑定,使用null作为 getter。 - 数字输入在空或无效时可能产生
undefined。复选框状态可以使用bind:checked和bind:indeterminate;单选按钮组使用bind:group。 - 自 5.6 起,输入支持
defaultValue/defaultChecked。自 5.57 起,选择支持defaultValue,包括表单重置行为。在提供默认值时检查绑定优先级。 - 自 5.47 起,支持可自定义的原生选择。在替换自定义选择小部件之前,检查浏览器支持和记录的
<selectedcontent>模式。 - 自 5.53 起,属性之间的 JavaScript 风格注释是有效的:
<div /* explanation */ class="card">。 - 自 5.52 起,
{@html}接受TrustedHTML。Trusted Types 支持不会清理任意输入;使用受信任的源或清理策略。
Each 块和片段
{#each items as { id, name }}解构条目。范围迭代可以使用{#each { length: 8 }, index}。- 对于其身份很重要的列表,优先使用稳定的项键。编辑项时,通过项对象绑定其属性,以便突变到达源。
- 片段在标记中声明,并使用
{@render snippet(...)}渲染。自 5.5 起,如果顶级片段不捕获实例状态,则可以从<script module>导出它们。 - 自 5.30 起,片段支持泛型。组件泛型使用
<script lang="ts" generics="T">。 - 在 Runes 模式下,组件变量动态渲染为
<Component />。递归组件可以导入自身。
Runes 和共享状态
状态和 Props
$state.raw跟踪重新赋值而不进行深度代理。将其用于整体替换的大值。$state.snapshot提取纯数据并尊重toJSON()。- 类实例不会深度代理。使用
$state字段,或自 5.31 起使用它们的首次构造函数赋值。响应式字段变为不可枚举的访问器;在将方法作为回调传递时保留this。 - 将响应式值传递给函数会传递其当前值。当函数需要未来值时,传递一个 getter。解构代理也会读取当前值。
- 使用
.svelte.js/.svelte.ts实现共享的 rune 逻辑。当消费者需要更改状态时,导出一个稳定的状态对象或访问器;直接导出重新赋值的 rune 状态是受限制的。 - 在 SSR 期间通过组件上下文限定特定于用户的状态。共享模块状态可能会跨请求泄漏。
$props.id()(在 5.20 中添加)给出一个组件实例 ID,该 ID 在 SSR 和水合之间匹配。$bindable()声明一个可绑定的 prop。Props 可以局部重新赋值;改变父级的非可绑定代理会引发所有权警告。回退值不会自动代理。- 保持
$state<T>()的实际未初始化类型(包括undefined),或提供有效的初始值。在访问站点使用缩小。
Derived 和 Effects
- 使用
$derived(expression)或$derived.by(fn)实现计算值。自 5.25 起,使用let声明的 Derived 可以重新赋值以实现乐观 UI;依赖项更改会重新计算它们。 - 解构的
$derived值保持响应式。返回的对象不会自动深度代理。引用相等性可以跳过下游工作。 - Effects 跟踪其最新运行的同步读取。在普通的异步回调中 await 之后的读取不会自动成为依赖项。
$effect在浏览器中运行。同步返回清理函数;将 effects 保留用于外部同步,并将用户触发的工作放在处理程序中。$effect.tracking()检测跟踪上下文。$effect.root()创建一个手动管理的作用域并返回一个释放器。getAbortSignal()(在 5.35 中添加)必须在 effect 或 derived 内部运行。其信号在重新执行或销毁时中止。将其用于由该响应式计算拥有的 fetch 工作。untrack(fn)从依赖项跟踪中排除读取。$inspect(...).with(fn)接收"init"/"update"后跟值。$inspect.trace(label?)(在 5.14 中添加)必须是跟踪函数中的第一条语句。$host()用于自定义元素并返回其宿主 DOM 元素。
运行时模块
- 自 5.40 起,
createContext<T>()提供类型化的上下文。自 5.57 起,它返回[get, set, has];has()在get()之前检查可用性,get()在未设置时会抛出异常。上下文查找包括当前组件和祖先。在初始化期间调用上下文访问器,并在脚本中的第一个await之前设置上下文。自 5.57.1 起,在 SSR 期间,稍后的setContext会抛出set_context_after_init。 svelte/reactivity提供SvelteMap、SvelteSet、SvelteDate、SvelteURL和SvelteURLSearchParams。Map/Set 条目不会深度响应式处理。- Svelte 5.57 添加了
SvelteMap.getOrInsert(key, value)和getOrInsertComputed(key, key => value)。当键不存在时,计算回调运行,包括正确处理现有的undefined条目。 MediaQuery和createSubscriber在 5.7 中引入。使用createSubscriber将外部事件连接到带有共享订阅设置和清理的跟踪读取。MediaQuery接受 SSR 回退;当 CSS 可以表达相同的行为时,使用 CSS。- 自 5.11 起,
svelte/reactivity/window提供尺寸、滚动位置、在线状态、屏幕位置和像素比的响应式.current值。在 SSR 期间考虑不可用的 window 值。 - 来自
svelte/events的on()使用声明式事件处理程序保留顺序并返回清理函数。使用<svelte:window>/<svelte:document>实现声明式全局监听器。 flushSync(fn?)同步刷新待处理的更新。createRawSnippet支持带有设置/清理的程序化标记。getAllContexts()提供当前上下文映射以进行程序化挂载;在初始化期间调用它。- 自 5.8 起,来自
svelte/motion的Spring和Tween替换了弃用的spring()/tweened()存储。两者都公开.target、.current、.set()和.of(fn)。Spring.set支持preserveMomentum;prefersReducedMotion支持无障碍动画。 - 自 5.55 起,动画导出包括
TweenOptions、SpringOptions、SpringUpdateOptions和Updater。 hydratable(key, fn)(在 5.44 中添加)序列化数据以便在水合期间重用。它使用 devalue 并支持嵌套的 promise。命名空间的键避免冲突。Kit 远程函数已经处理了这层。- 使用 CSP 时,自定义 SSR 集成必须为每个响应配置带有 nonce 的
render或静态哈希,并将匹配的值放在响应头中。Svelte 5.46 添加了渲染 CSP 支持;5.57 从svelte/server导出RenderOutput、SyncRenderOutput、Csp和Sha256Source。 - 对于工具,自 5.45 起,
print()将现代 Svelte AST 转换为源代码;parseCss()在 5.48 中引入。自 5.54 起,编译器选项css、runes和customElement可以是依赖于文件名的函数。在使用这些 API 之前,请阅读 Svelte 参考。
SvelteKit
新应用使用 Kit 3(npx sv create)。使用 npx sv migrate sveltekit-3 迁移 Kit 2 应用,然后处理生成的 TODO。Kit 2 指导仅适用于停留在 2.x 上的项目。
Kit 3 基线
- Kit 3 需要 Node 22.17、TypeScript 6、Svelte 5.57.1、Vite 8.0.12 和 vite-plugin-svelte 7。
- 配置位于
vite.config.ts中的sveltekit({...})内,Kit 选项位于顶层,与compilerOptions并列。Kit 3 不再读取svelte.config.js。 #lib通过 package.json 子路径导入替换$lib。编写文件扩展名,例如#lib/server/db.ts。- 文件名段
server,或src/routes之外的任何server目录,将模块标记为仅服务器端。文件名段remote,例如data.remote.ts或remote.ts,将模块标记为远程模块。 - 在
src/env.ts中使用来自@sveltejs/kit/env的defineEnvVars声明环境变量。从$app/env/private和$app/env/public导入值,并从$app/environment导入browser、building、dev、version。公共变量可以出现在app.html中,格式为%sveltekit.env.NAME%。$env/*和$app/environment是弃用的别名。 $app/stores已移除;使用$app/state。page.url是只读的;使用new URL复制。
...