mcpField
S
svelte5

svelte5

github.com/joshuadavidthomas开发6044 次安装14 周前更新
代码仓库

关于 svelte5

svelte5 是面向 Svelte 5 组件编写与审查的技能,适用于开发者。它以状态所有权、可见的数据流和语义化标记为核心,帮助识别旧语法与常见反模式。

主要功能

  1. 01Svelte 5 响应式设计原则
  2. 02组件状态与属性建模
  3. 03组件 API 与 HTML 语义审查
  4. 04代码异味检查与重写建议
  5. 05区分 Svelte 4 与 Svelte 5 项目

适用场景

  1. 01审查 Svelte 5 组件的数据流
  2. 02将副作用改为派生状态或事件处理
  3. 03检查无障碍与 SSR 状态风险

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/joshuadavidthomas/agent-skills --skill svelte5

安装后在 Claude Code 中输入/svelte5确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README.md
references/
actions-vs-components.md
actions.md
attachments.md
bindable-by-default.md
bindings-and-directives.md
class-state-common-mistakes.md
class-state-patterns.md
class-state-ssr-safety.md
component-patterns.md
context-identity.md
context-vs-scoped-state.md
debugging.md
deep-state-without-immutable-ceremony.md
effect-driven-state.md
imperative-api.md
prop-mirroring.md
read-tracked-reactivity.md
runes-common-mistakes.md
runes-component-api.md
runes-reactivity-patterns.md
semantic-html-first.md
shadcn-svelte-forms.md
snippets-as-render-functions.md
snippets-vs-slots.md
special-elements.md
ssr-state-leaks.md
state-ownership.md
static-runes.md
stores.md

详细介绍

Think in Svelte 5

你已经熟悉 Svelte 语法。这项技能会改变你的默认选择——设计组件、放置状态、建模响应性以及审查 UI 代码时,你会优先采用什么做法。

核心问题在于:Svelte 代码虽然能编译,但思路却像 React、Vue 或 Svelte 4——用 effect 代替派生值和事件,把 props 镜像到状态中,习惯性使用全局 store,默认双向绑定,使用可点击的 div,在新代码中使用 Svelte 4 组件 API。

组件是一个依赖关系清晰可见的小型响应式程序。保持数据流直接、状态归属明确、标记语义化;让编译器和 DOM 完成它们的工作。

这项技能是审查 Svelte 组件的通用入口;对于 SvelteKit 层面的关注事项,也请使用 sveltekit(参见交叉引用)。

将这些原则视为强默认做法,而非死板的规则:不确定时,选择能更明确地表达归属、依赖关系和用户语义的做法。

Svelte 的思维方式

让响应性一目了然

1. 响应性通过读取进行追踪。 $derived/$effect 会依赖其运行期间读取的内容;如果它意外重新运行,请检查它读取了什么,而不是依赖数组。参见 references/read-tracked-reactivity.md。

2. 派生状态用 $derived,而不是 $effect。 其他状态的纯函数结果应使用派生值;effect 用于副作用,而不是让变量保持同步。参见 references/effect-driven-state.md。


let doubled = $state(0);
$effect(() => { doubled = count * 2; });


let doubled = $derived(count * 2);

3. Effects 是逃生舱。 使用 $effect 前,先确认是否可以用派生值、事件处理器或 bind: getter/setter。只有在需要操作外部环境时才使用它——例如订阅、计时器、观察器、命令式 API、日志记录——并返回清理函数。

4. Runes 可静态分析。 它们是编译器语法,而不是运行时 hook——可复用状态应使用 .svelte.ts 类和工厂函数,而不是自定义 hook。参见 references/static-runes.md。

5. $state 是深层代理,不是 React 状态。 在局部数组和对象中直接修改变更的内容;无需遵循不可变更新的繁琐流程。参见 references/deep-state-without-immutable-ceremony.md。

将状态放在归属最明确的位置

6. 状态有所属。 局部交互状态 → 组件;可复用行为 → .svelte.ts 类;在后代间共享 → context;只有需要 store 契约时才用 store,而不是把每个变化的值都放进去。参见 references/state-ownership.md。

7. 除非你确实需要“草稿”,否则不要镜像 props。 将 props 复制到 $state 会产生两个事实来源——应从 props 派生,或者创建一个命名明确、可重置和提交的可编辑草稿。参见 references/prop-mirroring.md。


let { value } = $props();
let local = $state(value); // stale if parent changes


let { value } = $props();
let display = $derived(value.toUpperCase());

8. Context 共享的是身份,而不是提供者重新渲染。 将响应式对象/类放入 context,并修改其属性;替换普通值的行为不会像 React Provider 更新那样生效。参见 references/context-identity.md。

9. 在 SSR 应用中,模块级可变状态值得警惕。 在 SvelteKit 中,导出的可变实例会在请求之间泄漏——请使用工厂函数、context 或归属于请求的数据。参见 references/ssr-state-leaks.md。

围绕所有权设计组件 API

10. Props 描述输入;回调描述事件。 组件事件是回调 props;除非要保留旧的公共 API,否则新代码中应避免使用 createEventDispatcher。参见 references/component-patterns.md。


const dispatch = createEventDispatcher();
function handleClick() { dispatch('select', item); }


let { onSelect } = $props();
function handleClick() { onSelect?.(item); }

11. 双向绑定是一项 API 承诺。 $bindable 表示子组件可以修改由父组件拥有的状态——将其用于表单控件和有意设计为受控组件的场景,而不要将其作为默认做法。参见 references/bindable-by-default.md。

12. Snippet 是渲染函数,而不是改了名字的 slot。 当父组件提供 UI 时使用它们;为其参数添加类型,并按职责命名。参见 references/snippets-as-render-functions.md。

13. 包装组件应保留平台能力。 包装 button 意味着接受 button 属性,并保留 type、disabled、焦点和 ARIA。参见 references/wrapper-components-preserve-html.md。

让 HTML 和编译器发挥作用

14. 优先使用原生元素,再添加自定义行为。 button 已能处理键盘、焦点、禁用状态和无障碍功能;可点击的 div 则会拙劣地重造平台能力。参见 references/semantic-html-first.md。

15. 设计系统字段应保留表单语义。 在 shadcn-svelte 或 bits-ui 表单中,使用 Field.* 实现标签、分组、描述和错误信息——不要使用原始 div、单独导入 Label,也不要使用可点击的选项行。参见 references/shadcn-svelte-forms.md。

16. 组件负责标记;actions/attachments 负责 DOM 行为。 渲染 UI → component。将可复用的命令式行为附加到元素 → action 或 attachment。参见 references/actions-vs-components.md。

17. Svelte 5 语法应保持一致。 新代码使用 $props、onclick 风格的属性、snippets 和回调 props;除维护旧代码外,不要混用旧语法。参见 references/svelte5-syntax-discipline.md。

18. 为边界添加类型,而不是事无巨细地添加类型。 非简单组件应定义 Props 类型;为 snippets 和回调添加类型;包装组件使用 svelte/elements;避免在边界使用宽泛的 any。参见 references/typescript.md。

运行审查

  1. 先检测版本。 查看 package.json 中的 svelte 主版本,并检查 svelte.config.*。在 Svelte 5 项目中,标记 Svelte 4 模式(export let、on:event、<slot>、createEventDispatcher);在 Svelte 4 项目中,除非任务是迁移,否则不要建议使用仅适用于 Svelte 5 的语法。
  2. 应用上述原则;扫描下方的异味索引。 提出重写方案前,先打开链接的参考资料。
  3. 仅凭证据或明显的规模判断性能。 为已识别的 {#each} 添加 key,将繁重的工作从标记中移至 $derived,避免不必要的双向绑定。大多数代码无需手动优化。
  4. 组织输出: 先列出影响最大的事项(正确性、响应性、无障碍、SSR 泄漏),再给出建议的重写方案(以最小的有效改动为准),最后列出可选的改进。每一点都应关联到行为、可维护性或用户影响——不要纠缠于每个风格小问题。

代码异味索引

查找异味;上面的原则提供了修复方法。

代码异味参考
新代码中使用旧版 Svelte 语法svelte5-syntax-discipline
Effect 赋值给派生值effect-driven-state
Effect 响应控件变化effect-driven-state
Effect 转换绑定值bindings-and-directives
Effect 神秘地重新运行read-tracked-reactivity
在辅助函数或 hook 中调用 Runestatic-runes
对本地状态进行繁琐的不可变更新deep-state-without-immutable-ceremony
将 Prop 复制到本地状态prop-mirroring
默认使用全局 store/所有权不明确state-ownership
替换 Context 值而非修改它context-identity
在 SvelteKit 中导出可变单例ssr-state-leaks
使用 createEventDispatcher 发出事件component-patterns
习惯性使用 $bindablebindable-by-default
类似 Slot 的 API(export let、<slot>)snippets-as-render-functions
可点击的 div/spansemantic-html-first
用原始包装组件重建 shadcn-svelte 表单shadcn-svelte-forms
隐藏原生行为的包装组件wrapper-components-preserve-html
由 Action 管理标记/状态actions-vs-components
动态列表未使用 keybindings-and-directives
组件边界处使用宽泛的 anytypescript
{@html} 包含用户内容template-tags
组件行为未经测试testing

交叉引用

  • sveltekit — 路由、布局、load、表单操作、远程函数、Cookie、身份验证、端点、重定向、服务器错误、应用级 SSR/数据流

评论

支持 Markdown