rxliuli blog

rxliuli blog

马上订阅 rxliuli blog RSS 更新: https://blog.rxliuli.com/atom.xml

svelte5:一个更糟糕的 vue3

2025年3月4日 22:05

背景

svelte5 在去年 10 月发布,据说是 svelte 发布以来最好的版本。其中,他们主要为之自豪的是 runes,这是一个基于 proxy 实现的一个反应式状态系统。但经过 vue3 composition api 和 solidjs signals,吾辈并未感到兴奋。相反,这篇博客将主要针对吾辈在实际项目中遇到的 svelte5 问题进行说明,如果你非常喜欢 svelte5,现在就可以关闭页面了。

runes 只能在 svelte 组件或者 .svelte.ts 文件中

例如,当吾辈像 react/vue 一样用 runes 编写一个 hook,例如 useCounter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
export function useCounter() {
let count = $state(0)
return {
get value() {
return count
},
inc() {
count++
},
dec() {
count--
},
}
}

const counter = useCounter()
console.log(counter.value)
counter.inc()

但这个函数不能放在普通的 .ts 文件,必须使用 .svelte.ts 后缀并让 @sveltejs/vite-plugin-svelte 编译这个文件中的 runes 代码,否则你会得到 $state is not defined。这也包括 unit test,如果想要使用 runes(通常是测试 hooks/svelte component),文件名也必须以 .svelte.test.ts 结尾,真是糟糕的代码感染。

https://svelte.dev/docs/svelte/what-are-runes#:~:text=Runes%20are%20symbols%20that%20you%20use%20in%20.svelte%20and%20.svelte.js%20/%20.svelte.ts%20files%20to%20control%20the%20Svelte%20compiler

使用 runes 编写 hooks 传递或返回 runes 状态须用函数包裹

看到上面的 useCounter 中返回的值被放在 get value 里面了吗?那是因为必须这样做,例如如果尝试编写一个 hooks 并直接返回 runes 的状态,不管是 $state 还是 $derived,都必须用函数包裹传递来“保持 reaction”,否则你会得到一个错误指向 https://svelte.dev/docs/svelte/compiler-warnings#state_referenced_locally。当然这也包括函数参数,看到其中的讽刺了吗?

1
2
3
4
5
6
7
8
9
10
11
12
import { onMount } from 'svelte'

export function useTime() {
let now = $state(new Date())
onMount(() =>...

剩余内容已隐藏

查看完整文章以阅读更多