DEBUG.WIKI
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
雨云;给项目一台云服务器
RackNerd;$21.99/年 · 1GB KVM

Svelte eager 变量未定义

let x = $state.eager(d) 已写却在客户端报 x is not defined,SSR 又正常。检查旧声明转换与 Svelte 5.57.1 正式修复。

代码明明有 let x = $state.eager(d),客户端却报 ReferenceError: x is not defined,同一组件的 SSR 输出又正常。先检查客户端编译结果有没有保留这条变量声明。

Svelte 5.57.0 有一个明确的声明转换问题:$state.eager(...) 作为 let、const 的初始化表达式时,客户端可能丢掉整项声明,后面的模板仍然引用变量。正式 5.57.1 已修复该路径,已核对的 5.57.2 也包含修正。

对照声明与直接表达式

下面是体现故障形状的完整组件示例,仅供受控环境检查编译输出:

<script>
  let n = $state(2);
  let d = $derived(n * 10);
  let x = $state.eager(d);
</script>

<p>{x}</p>

旧客户端输出保留了 n、d,却没有声明 x,生成的文本更新代码仍使用 x。服务端转换保留变量,所以首次 HTML 看起来正常,客户端执行后才失败。

同一个 rune 放在模板表达式里,或放在类字段路径中,走的是不同转换入口。它们能工作,不代表变量声明入口也没有问题。混合声明、解构以及初始化值恰好是 rune 调用的 {@const},也不能只用直接表达式的结果代替检查。

若客户端确实生成了 x 的声明,则另查作用域、拼写与条件执行路径。普通 JavaScript 的未定义变量不会因为升级这项编译器修复而自动变正确。

保留声明的正式修复

修正后的客户端变量访问器把 $state.eager 纳入保留并继续转换的路径,不再落到空声明。选择与项目兼容、包含该改动的正式版本后,检查实际编译器依赖,重新生成客户端产物。

只能短期保留旧包时,可以评估把所需 eager 读取写在模板使用位置,避开这一项声明转换,但须重新核对读取时机。let x = ... 的初始化与模板反复求值不必具有相同语义,不能机械替换所有变量后宣称行为完全一致。

$state.eager 用于异步更新协调期间及时给用户操作反馈,不是一般意义上的 $derived 替代品。把它赋给普通局部变量,也不能据此承诺这个变量以后会自动跟随所有状态变化。应按页面实际需要保留响应式关系。

这个版本结论只覆盖 $state.eager 声明被丢弃。其他 rune 的声明问题要另核对对应转换,不能把相近报错都写成 5.57.1 已一并修复。

验收时分别检查客户端产物中变量仍被声明、浏览器不再出现该 ReferenceError,以及 SSR 与客户端显示符合预期。需要即时反馈的交互还应在真实异步等待期间测试;只看到静态数值 20,不足以验证更新时机。