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
属性的对象,当媒体查询匹配时,该属性为真。prefersReducedMotion
是 MediaQuery
的一个实例,如果用户表达了减少动态效果的偏好,它会匹配,从而帮助你构建无障碍应用程序。这两者均使用 createSubscriber
机制,其提供了一种在效果中读取值时轻松设置事件监听器的方法。
第 6 天:Spring 和 Tween
我们现在有了现代的基于状态的替代方案,用于替换旧的 spring
和 tweened
存储。真是顺滑!
第 7 天:更优的教程导航
许多人不喜欢教程的下拉导航——本质上是一个巨大且难以使用的 <select>
元素——因此我们将其替换为层次化的菜单。因为菜单完全由 <details>
和 <a>
元素组成,所以无障碍功能是默认支持的。甚至在JavaScript禁用的情况下,也可以导航教程!
第 8 天:函数绑定
现在你可以通过 bind:value={get, set}
来验证和转换绑定的值。这个功能适用于所有绑定,甚至是组件上的绑定。
第 9 天:错误和警告文档
当 Svelte 发出警告或错误时(无论是在构建时、编译器运行时,还是在应用程序运行于服务端或浏览器时),现在都会附带一个链接,指向文档中的对应条目,提供描述(为了节省字节量,生产版本中省略)以及——在某些情况下,还有更多的信息说明它为何发生以及你可以如何修复。
第 10 天:SvelteKit 的 init 钩子
许多人希望有一个地方可以执行在 SvelteKit 应用启动前的异步设置工作。现在,你可以从 hooks.server.js
和 hooks.client.js
中导出一个 init
函数,在所有其他事情发生之前,该函数会被等待完成。
第 11 天:svelte/reactivity/window
今天我们新增了一个完整的新模块。svelte/reactivity/window
导出了多种响应式值,例如 innerWidth
、innerHeight
、scrollX
、scrollY
等等。像第5天介绍的 MediaQuery
以及第6天的 Spring
和 Tween
一样,这些也是具有响应式 current
属性的类实例,可以在你的模板和派生/效果中使用。后台由 Svelte 处理所有监听器相关的操作。
第 12 天:SvelteKit 中的自定义类型传输
在 SvelteKit 应用中运行于服务器上的 load
函数,不限制只返回可被 JSON 序列化的数据。您可以返回 Maps、Sets、Dates、带有循环引用的对象,甚至 Promises,SvelteKit 将在服务器上处理序列化,而在浏览器中处理反序列化。
从今天起,您还可以返回一些不属于语言内建的东西,例如包含状态的类,数据库 ORM 库返回的类,或任何其他内容——只需从 hooks.js
文件中导出一个 transport
对象,并提供 encode
和 decode
方法即可。
第 13 天:机器人的崛起
对于那些通过 Cursor、Copilot、Claude、Bolt、v0 或其他接口,使用 LLMs 来帮助编写代码的人,我们现在将文档发布为一组选定的适合机器阅读的 llms.txt
文件。这是一个实验性功能,并将随着时间的推移不断发展。例如,这里有一个 贪吃蛇游戏,完全由 Sonnet 3.5 无需额外提示生成。
感谢 Didier Catz 和 Stanislav 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 的用户特别有用。
就到这里啦!感谢您的关注,祝所有庆祝节日的人圣诞快乐!