Svelte 的 children snippet 不显示:检查 preserveWhitespace
组件接到显式 children snippet,却只渲染空白。检查组件标签内 snippet 外的换行是否被作为默认内容,按保留空白的真实需求调整。
子组件收到显式 {#snippet children()},界面却没有其中的元素;产物甚至可能提示 Duplicate key "children" in object literal。如果编译器开启了 preserveWhitespace: true,检查 component 标签内、snippet 外面是否还留有换行和缩进。
Svelte 5.56.9 有明确的这组条件。该选项把原本可能被裁掉的空白变成有意义内容,不能一边要求保留空白,一边假设 snippet 周围的空白永远不参与默认内容生成。当前 5.57.3 的相应编译路径仍分别处理 snippet 属性与默认子内容,不应只靠升级承诺这组配置不再冲突。
空白也可能占据默认 children
例如 Child 通过 $props() 读取 children 并 {@render children?.()},调用方写成:
<Child>
{#snippet children()}
<p>应当显示的内容</p>
{/snippet}
</Child>
preserveWhitespace 为 true 时,snippet 前后的文本节点可能进入隐式默认内容。显式 snippet 与这份默认内容都使用 children 槽位,后写入的空白属性便可能盖住前者。这个覆盖可能没有运行时异常或 hydration mismatch,仍需确认目标子树实际存在。
先核对实际传给 Svelte 编译器的选项,而不是只看 bundler 的生产 minify 设置。插件可能把二者关联起来,造成开发保留空白、生产裁掉空白,于是只有开发环境丢内容。单独改变压缩器并不能自动解释编译器收到的配置。
不需要额外默认内容时,只去掉 snippet 外空白
必须保留其他位置空白时,可局部写成没有额外默认文本的结构:
<Child>{#snippet children()}
<p>应当显示的内容</p>
{/snippet}</Child>
这里仅移除了 Child 标签与 snippet 之间的空白,snippet 自己内部的内容仍保留。格式化工具若重新插入外围换行,需要检查格式化后的真实源码,而不是只修改一次后便假定设置永久有效。
项目本来不需要保留模板空白时,也可在实际编译配置中恢复 preserveWhitespace: false。它是默认值,但会影响其他组件的空白与布局,需沿插件支持的配置入口修改,并检查依赖空格的内联内容。不要为了一个弹层把全项目所有换行或文本空格删掉。
Child 也可以把业务 snippet 改成有明确名称的其他 prop,并同步调用方与类型,但这会改变组件接口。第三方库不支持这种接口时,不能只改传入名称后宣称内容恢复。
验收检查编译产物中同一默认内容只有预期的 children,界面实际创建了目标元素,再对照客户端、服务端输出和水合。还要保留纯命名 snippet、确实需要默认空白内容的组件,避免解决一个消失子树后让其他组件的存在性分支改变。


