Skip to main content

Svelte 降临

二十四天,二十四个功能

去年十二月,Svelte Society 以降临节日历的形式发布了一系列Svelte主题的节日代码挑战

今年,我们反其道而行之:这次轮到你们放松,而由我们来接受挑战。从今天起到圣诞节,我们的目标是每天发布一个新东西,无论是 Svelte 或 SvelteKit 的新功能,还是网站的改进。

关注 @svelte.dev@sveltesociety.dev,每天查看我们正在开发的内容。

第 1 天:错误边界

这是一个期待已久且需求量很大的功能,允许你在渲染过程中隔离并从错误中恢复。

第 2 天:省略 as 的 each

如果你只想在 {#each ...} 块中渲染某个内容 n 次,并且不关心值,那么现在可以省略 as 部分。

第 3 天:导出代码片段

现在可以从组件的 <script module> 中导出代码片段,以便在其他组件中使用,只要这些片段不引用属于组件实例的内容即可。

第 4 天:表单控件默认值

当你重置表单时,每个 <input> 元素的值会恢复为 defaultValue。通常情况下,这是一个空字符串,但现在你可以直接在模板中控制它。

第 5 天:MediaQuery、prefersReducedMotion 和 createSubscriber

今天是三合一的更新。new MediaQuery(...) 提供了一个包含响应式 current 属性的对象,当媒体查询匹配时,该属性为真。prefersReducedMotionMediaQuery 的一个实例,如果用户表达了减少动态效果的偏好,它会匹配,从而帮助你构建无障碍应用程序。这两者均使用 createSubscriber 机制,其提供了一种在效果中读取值时轻松设置事件监听器的方法。

第 6 天:Spring 和 Tween

我们现在有了现代的基于状态的替代方案,用于替换旧的 springtweened 存储。真是顺滑!

第 7 天:更优的教程导航

许多人不喜欢教程的下拉导航——本质上是一个巨大且难以使用的 <select> 元素——因此我们将其替换为层次化的菜单。因为菜单完全由 <details><a> 元素组成,所以无障碍功能是默认支持的。甚至在JavaScript禁用的情况下,也可以导航教程!

第 8 天:函数绑定

现在你可以通过 bind:value={get, set} 来验证和转换绑定的值。这个功能适用于所有绑定,甚至是组件上的绑定。

第 9 天:错误和警告文档

当 Svelte 发出警告或错误时(无论是在构建时、编译器运行时,还是在应用程序运行于服务端或浏览器时),现在都会附带一个链接,指向文档中的对应条目,提供描述(为了节省字节量,生产版本中省略)以及——在某些情况下,还有更多的信息说明它为何发生以及你可以如何修复。

第 10 天:SvelteKit 的 init 钩子

许多人希望有一个地方可以执行在 SvelteKit 应用启动前的异步设置工作。现在,你可以从 hooks.server.jshooks.client.js 中导出一个 init 函数,在所有其他事情发生之前,该函数会被等待完成。

第 11 天:svelte/reactivity/window

今天我们新增了一个完整的新模块。svelte/reactivity/window 导出了多种响应式值,例如 innerWidthinnerHeightscrollXscrollY 等等。像第5天介绍的 MediaQuery 以及第6天的 SpringTween 一样,这些也是具有响应式 current 属性的类实例,可以在你的模板和派生/效果中使用。后台由 Svelte 处理所有监听器相关的操作。

第 12 天:SvelteKit 中的自定义类型传输

在 SvelteKit 应用中运行于服务器上的 load 函数,不限制只返回可被 JSON 序列化的数据。您可以返回 Maps、Sets、Dates、带有循环引用的对象,甚至 Promises,SvelteKit 将在服务器上处理序列化,而在浏览器中处理反序列化。

从今天起,您还可以返回一些不属于语言内建的东西,例如包含状态的类,数据库 ORM 库返回的类,或任何其他内容——只需从 hooks.js 文件中导出一个 transport 对象,并提供 encodedecode 方法即可。

第 13 天:机器人的崛起

对于那些通过 Cursor、Copilot、Claude、Bolt、v0 或其他接口,使用 LLMs 来帮助编写代码的人,我们现在将文档发布为一组选定的适合机器阅读的 llms.txt 文件。这是一个实验性功能,并将随着时间的推移不断发展。例如,这里有一个 贪吃蛇游戏,完全由 Sonnet 3.5 无需额外提示生成。

感谢 Didier CatzStanislav Khromov 的贡献!

第 14 天:带动画卸载

现在,如果您需要以编程方式挂载和卸载组件,可以向 unmount 方法传递一个 outro: true 选项,在从 DOM 中移除之前播放过渡动画。

第 15 天:调试增强功能

全新的 $inspect.trace(...) 特性可以详细提供哪些状态变化导致派生或效果重新运行的信息。

第 16 天:$app/state

SvelteKit 的 $app/stores 模块(例如用于获取当前页面信息),现在有了一个基于现代 Svelte 5 状态的替代品:$app/state。它提供了相同的信息,但使用细粒度状态,而且没有笨重的 $ 前缀。$app/stores 现在已被弃用,并将在明年的 SvelteKit 3 中移除。

您可以通过在 SvelteKit 应用中运行以下命令自动迁移:

npx sv migrate app-state

第 17 天:更好的 IntelliSense

为支持 Svelte for VS Code 扩展等功能的语言工具所使用的解析器,与 Svelte 编译器使用的是同一个解析器。直到今天,如果遇到语法错误,该解析器会失败,这让您在编写代码时难以获得自动补全功能。

我们刚刚修复了这个问题。安装项目中最新版本的 Svelte,确认您的扩展已更新,当您编写组件时就能感受到畅快的编码体验。

第 18 天:Playground 悬停功能

如果您一直好奇 Svelte 编译器是如何工作的,今天的更新正是为您准备的。如果进入 playground 并打开 AST 输出标签,您将看到编译器操作的抽象语法树。从今天起,悬停在编辑器中的代码上将突出显示 AST 中相应的部分,反之亦然。单击任意代码片段将展开树并滚动到该 AST 节点。

JS 和 CSS 输出标签也已升级——它们现在使用源码映射来突出显示输入代码对应的输出代码,反之亦然。我们计划利用这一特性进一步完善源码映射,从而随着时间推移改善调试体验。

第 19 天:单文件 SvelteKit 包

默认情况下,SvelteKit 使用一种称为“代码分割”的技术,因此您只会加载当前页面需要的 JavaScript 和 CSS。这有助于在应用程序变得非常庞大时保持快速加载。

某些情况下,代码分割并不适用——您可能真正需要的是整个应用只有一个 .js 文件和一个 .css 文件。SvelteKit 现在通过 output.bundleStrategy 选项支持这种需求。

第 20 天:Vim 模式

playground 曾有一个隐藏的 Vim 模式,可以通过在网址后附加 ?vim=true 激活,但该模式存在一些问题。我们修复了这些问题,并在 playground 和教程中添加了一个切换开关,可以在访问间记住您的偏好。但不用担心:与普通的 Vim 模式不同,您可以通过再次关闭它(或关闭标签页)退出。

第 21 天:基于哈希的路由

SvelteKit 现在支持基于哈希的路由,除了默认的基于路径名的路由。这对于纯客户端应用(包括通过 Electron 或 Tauri 构建的应用)或在无法控制 Web 服务器时需要将所有内容放在单个页面的情况中非常有用。

这种方式有几个注意点——您无法使用服务器渲染(或任何服务器逻辑),并需要确保所有内部链接都以 /#/ 开头,否则无法正常工作。除此之外,它与任何其他 SvelteKit 应用一样。

第 22 天:独立式应用

继第19天引入 bundleStrategy 选项和昨天实现的基于哈希的路由后,我们现在可以通过设置 bundleStrategy: 'inline' 选项生成完全独立的应用。结合 Vite 的 assetsInlineLimit 选项,可以将整个 SvelteKit 应用——代码、样式、字体、图片、音频及其他内容——放入单个 .html 文件,甚至可以通过软盘分享。

第 23 天:从 Playground 下载应用

我们为 playground 的工具箱添加了一个“下载应用”选项——选择它后,会将应用和您导入的任何依赖包打包成 zip 文件,下载到您的机器上,方便您在自己喜欢的编辑器中继续工作。

第 24 天:内置 clsx 支持

Svelte 现在使用 clsx 来解析 class 属性,这意味着您可以通过对象和数组来有条件地添加和删除类。这比 class: 指令更强大、更灵活,而且——因为是 Svelte——依然可以对未使用的 CSS 进行死代码消除。该功能对使用 Tailwind 的用户特别有用。


就到这里啦!感谢您的关注,祝所有庆祝节日的人圣诞快乐!