前言
大家好,我是 AutoForm 的前端负责人。
最近 Svelte 5 发布了,带来了全新的响应式系统 Runes。作为一名长期被 React Hooks 依赖项数组折磨的开发者,我第一时间在公司的核心项目——AutoForm 智能表单填充 SDK 中尝试了 Svelte 5。
结果令人震惊:打包体积减少了 80%,初始化速度提升了 87%。今天就来分享一下这次重构的实战经验。
为什么要重构?
我们的 SDK 需要嵌入到客户的各种系统中(React, Vue, jQuery 等)。之前的版本是用 React 写的,存在几个痛点:
- 体积大:React + ReactDOM 即使压缩后也有 40KB+,对于一个挂件来说太重了。
- 样式冲突:虽然用了 CSS Modules,但还是偶尔会被宿主页面的全局样式污染。
- 性能开销:React 的运行时 Diff 在低端机上会有明显的卡顿。
Svelte 的 "无运行时" 和 "原生 DOM 操作" 特性,完美契合 SDK 的需求。
Svelte 5 新特性:Runes 实战
Svelte 5 最大的改变就是引入了 Runes(符文),这是一种显式的响应式声明方式,有点像 Vue 3 的 Refs,但更简洁。
1. 状态定义:$state
以前在 Svelte 4 中:
let count = 0;
现在:
let count = $state(0);
看起来变复杂了?但它带来了巨大的好处:响应式不再局限于组件内部。我们可以把状态提取到 .ts 文件中,轻松实现跨组件状态共享,完全不需要 Redux 或 Context。
// store.ts
export class FormStore {
formData = $state({});
updateField(key, value) {
this.formData[key] = value;
}
}
2. 派生状态:$derived
let double = $derived(count * 2);
这比 React 的 useMemo 聪明多了,它自动追踪依赖,而且只有在真正被使用时才计算。
3. 副作用:$effect
$effect(() => {
console.log('count changed:', count);
return () => {
console.log('cleanup');
};
});
终于不用写依赖数组了!Svelte 编译器会自动分析依赖。
遇到的坑与解决方案
1. Web Component 封装
Svelte 5 对 Web Component 的支持更加完善了。我们通过 <svelte:options customElement="autoform-widget" /> 轻松生成了自定义元素。
坑:Shadow DOM 中的样式隔离太彻底,导致外部无法定制主题。
解:使用 CSS Variables。我们在 Host 上定义 --primary-color,组件内部使用 var(--primary-color)。
2. 事件通信
在 Web Component 中,Svelte 的事件默认不会冒泡出 Shadow DOM。我们需要手动 dispatch composed: true 的事件。
const dispatch = createEventDispatcher();
// 这样是不行的,外界听不到
// dispatch('done');
// 必须这样
element.dispatchEvent(new CustomEvent('done', {
bubbles: true,
composed: true
}));
总结
Svelte 5 的开发体验简直是"回不去了"。它既有 React 的灵活性,又有 Vue 的简洁性,还有原生 JS 的性能。
对于 SDK、挂件、微前端子应用这类对体积和性能敏感的场景,Svelte 5 是目前的最优解。
互动话题:你们公司开始用 Svelte 了吗?欢迎在评论区留言讨论!
👉 官网地址:51bpms.com