首页 / Svelte 5 入门教程 / $inspect 与调试技巧

Svelte 5 入门教程

$inspect 与调试技巧

本教程共 50 篇 · 第 36 篇 · 更新于 2026-08-05 · 约 6 分钟阅读

SvelteSvelte 5$inspect调试编译器警告

36. $inspect 与调试技巧

本节目标:学会用 $inspect rune 实时追踪响应式状态变化,掌握 $inspect().with()$inspect.trace() 的高级用法,了解编译器警告/错误的处理和常用调试手段。

$inspect 基础

调试时你最常做的事就是 console.log。但响应式状态变化时,你往往想知道”每次变化后的值是多少”,手动写 console.log 很难追上。

Svelte 5 提供了 $inspect rune,它相当于会自动重跑的 console.log——只要你传给它的值变了,它就自动打印一次:

<script>
	let count = $state(0);
	let message = $state('hello');

	// count 或 message 变化时自动打印
	$inspect(count, message);
</script>

<button onclick={() => count++}>加 1</button>
<input bind:value={message} />

点击按钮时,控制台会输出 count 的新值;输入文字时,会输出 message 的新值。你不用手动在事件处理器里写 log。

Note

$inspect 只在开发环境生效。生产构建时它会被编译成空操作(noop),不会影响性能。

深度追踪

$inspect 会深度追踪响应式状态。这意味着你修改对象或数组内部的属性,它也能捕获到:

<script>
	let user = $state({ name: '张三', age: 25 });

	$inspect(user);

	function growUp() {
		user.age++; // 修改内部属性,$inspect 也会触发
	}
</script>

<button onclick={growUp}>长大一岁</button>

每次点击按钮,user 对象的 age 变化都会触发 $inspect 打印,即使你改的是对象内部属性而不是整个变量。

$inspect().with():自定义处理

默认情况下 $inspectconsole.log 输出。如果你想自定义处理逻辑(比如触发断点、发送到远程日志),用 .with() 方法:

<script>
	let count = $state(0);

	$inspect(count).with((type, value) => {
		// type 是 'init'(首次)或 'update'(变化时)
		if (type === 'update') {
			console.trace(`count 变成了 ${value}`);
		}
	});
</script>

<button onclick={() => count++}>加 1</button>

回调函数的第一个参数是 "init""update",表示是首次执行还是状态变化触发。后续参数就是你传给 $inspect 的值。

Tip

.with() 回调里写 debugger 语句,可以在状态变化时自动暂停代码执行,方便你在 DevTools 里检查调用栈和局部变量。

$inspect.trace():追踪函数重跑

$inspect.trace() 是 5.14 引入的调试工具。它用于追踪某个函数的重复执行,告诉你哪些响应式状态导致了函数重新运行

<script>
	import { doSomeWork } from './utils.svelte.js';

	let theme = $state('light');
	let data = $state([]);

	$effect(() => {
		$inspect.trace(); // 必须是函数体的第一条语句
		doSomeWork(theme, data);
	});
</script>

当这个 $effect 因为某个状态变化而重新执行时,控制台会打印出具体是 theme 还是 data 触发的重跑。这在排查”为什么我的 effect 总是不停重跑”时特别有用。

$inspect.trace() 接受一个可选的标签参数:

$inspect.trace('我的副作用'); // 控制台输出时带上标签
Note

$inspect.trace() 必须是函数体的第一条语句,否则不会生效。它只在开发环境有效。

svelte-ignore 注释

Svelte 编译器会在编译时检查你的代码,发现潜在问题就发警告。最常见的是无障碍(a11y)警告,比如:

<!-- A11y: Avoid using autofocus -->
<input autofocus />

有时候你确实需要这么做,警告是误报。这时用 svelte-ignore 注释来屏蔽:

<!-- svelte-ignore a11y_autofocus -->
<input autofocus />

注意事项:

  • 注释必须放在触发警告的那行代码上方
  • 可以同时屏蔽多条规则,逗号分隔
  • 可以在规则后加括号写说明
<!-- svelte-ignore a11y_click_events_have_key_events, a11y_no_static_element_interactions (自定义交互元素) -->
<div onclick={handleClick}>...</div>
Tip

不要滥用 svelte-ignore。每个被忽略的警告都可能是真实的无障碍问题。只有确认是误报时才使用。

编译器警告与错误

Svelte 编译过程会产生两类消息:

编译器警告(warning):代码能编译通过,但可能有问题。最常见的是 a11y 相关的警告(如 a11y_autofocusa11y_click_events_have_key_eventsa11y_missing_attribute 等)。其他还有 unused_export_let(导出的 prop 未使用)等。

编译器错误(error):代码无法编译。比如重复的属性名、无效的事件处理器、animate: 指令使用位置不对等:

<!-- 错误:事件属性必须是表达式,不能是字符串 -->
<button onclick="handleClick()">点击</button>

<!-- 正确 -->
<button onclick={handleClick}>点击</button>

编译错误会直接阻止构建,你必须修复才能继续。

运行时警告与错误

除了编译期,Svelte 在运行时也会报错和警告。常见的运行时错误包括:

  • state_proxy_equality_mismatch:在 Set/Map 中使用 $state 代理对象导致相等性判断出错
  • effect_update_depth_exceeded$effect 互相触发形成无限循环
  • lifecycle_outside_component:在组件生命周期外调用了 onMount 等函数

运行时警告不会中断程序,但建议认真对待,它们往往指向潜在的 bug。

调试工具汇总

工具用途适用场景
$inspect(value)自动追踪状态变化日常调试
$inspect(value).with(fn)自定义处理变化事件断点、远程日志
$inspect.trace()追踪函数重跑原因排查 effect 频繁重跑
flushSync()强制执行排队的副作用测试中验证 DOM 状态
svelte-ignore屏蔽编译器警告确认误报时
VS Code 插件语法高亮、类型检查、错误提示日常开发
svelte-check命令行类型检查CI/CD 流程
Tip

浏览器的 DevTools 也是调试利器。在 Sources 面板中你能看到 Svelte 编译后的代码,在 Elements 面板可以直接检查 DOM。配合 $inspect 的自动追踪,调试体验相当顺畅。

本节回顾

  • $inspect(value) 会自动追踪状态变化并打印,只在开发环境生效
  • $inspect().with(fn) 用自定义回调替代 console.log,可用于触发断点
  • $inspect.trace() 追踪函数重跑原因,必须是函数体第一条语句
  • <!-- svelte-ignore 规则名 --> 可屏蔽误报警告,可写多条规则
  • 编译器错误会阻止构建,必须修复;警告可选择性忽略
  • 运行时错误指向潜在的响应式 bug,需要认真排查