5 ms·
This is (surprisingly) almost identical to the Reactivity Transform explorations we did in Vue: https://vuejs.org/guide/extras/reactivity-transform.html https:/
by EvanYou 3y ago
This is (surprisingly) almost identical to the Reactivity Transform explorations we did in Vue: https://vuejs.org/guide/extras/reactivity-transform.html https://vuejs.org/guide/extras/reactivity-transform.html
let count = $ref(0)
const double = $computed(() => count * 2)
watchEffect(() => {
console.log(double)
})
We started experimenting with this ling of thought almost 3 years ago:
- First take (ref sugar), Nov 2020: https://github.com/vuejs/rfcs/pull/228 https://github.com/vuejs/rfcs/pull/228
- Take 2, Aug 2021: https://github.com/vuejs/rfcs/pull/368 https://github.com/vuejs/rfcs/pull/368
- Take 3, Nov 2021: https://github.com/vuejs/rfcs/discussions/369 https://github.com/vuejs/rfcs/discussions/369
We provided it as an experimental feature and had a decent number of users trying it out in production. The feedback wasn't great and eventually decided to drop it. https://github.com/vuejs/rfcs/discussions/369#discussioncomment-5059028 https://github.com/vuejs/rfcs/discussions/369#discussioncomm...
- wentin 3y agoHi Evan You! (Hi from wentin) It's great to see you here in this thread. It's such a wonderful gesture for the open-source community to collaborate in this manner, by sharing valuable lessons learned the hard way. It’s intriguing to see where the Svelte exploration will lead. Will it face disapproval or achieve success? While I agree that both implementations have arrived at the same place (almost serendipitously), their origins differ. For Vue, it's about adding the syntactic sugar by dropping .value, making it less explicit and more magical. In contrast, Svelte made the change to make things more explicit and reduce the “black magicness” from the svelte compiler, and bring it more similar to javascript. This difference might trigger totally different reaction, time will tell. Looking forward to more insightful discussions!
- tipiirai 3y agoI guess we are all waiting for Rich Harris to step in and comment on this one. I'm sure he has followed this Vue experimentation and has a clear argument to make. At least I hope so.
- vjerancrnjak 3y agoAll of this looks like MobX
- ramesh31 3y ago>All of this looks like MobX Shhhh. Don't tell the Vue/Svelte community that they're just reinventing the React ecosystem on a 5 year delay. It will spoil all of their fun.
- kecupochren 3y agoMobX is not that known unfortunately. It kills me inside.
- rich_harris 3y agoMichel and I have been internet acquaintances for years, and we've even talked about this stuff IRL. MobX certainly isn't something we just somehow never learned about! But anyway: it's absurd to compare this with React+MobX. MobX replaces useState, sure, but you're still re-rendering entire components on each change (which is why MobX explicitly recommends that you break apart your app into many small components, regardless of whether that's a boon to readability and maintainability. By contrast, Svelte (and Solid, and other frameworks) understand signals on a much deeper and more optimal level. They're really not the same thing at all.
- vjerancrnjak 3y agoMobX does not rerender entire components. Unlike Redux at that time (~2016), it was a first approach where minimum rendering was happening effortlessly. You can have a list of components where each component references a bit of global state and rerenders only if that bit changes, even though the list might have enlarged or other elements changed. Last time I used it (2016-2020), they used all of the tricks of the trade, get, set object attributes, dropped decorators and it still worked the same.
- rich_harris 3y ago
- frodowtf 3y agoFunny, I also thought of Vue immediately.
- rich_harris 3y agoHi! First up — not that it matters, but since people will wonder — our design wasn't informed by the Reactivity Transform. We evaluated something close to 50 designs, some of them extremely wacky, before settling on runes, and it wasn't until after that time that the Reactivity Transform was brought to our attention. Nevertheless, it's interesting and validating that we landed on such similar approaches. While the Reactivity Transform failed, it did so for reasons that I don't think apply to us: - $state and $ref are quite different. $state doesn't give you access to the underlying object, so there's no conversion necessary between reactive variables and ref objects (either in your head or in code). - There's strict read/write separation. Anyone with access to a ref has the ability to change its value, which definitely causes problems at scale. It's something that React, Solid and Svelte 5 get right. - Reactivity Transform introduces things like $() for magic destructuring and $$() for preserving reactivity across boundaries. We're instead encouraging people to use familiar JavaScript concepts like functions and accessors - There are already a lot of different ways to work with Vue — SFCs vs non-SFCs, template syntax vs JSX, composition API vs options API, `<script>` vs `<script setup>`... on top of that, adding a new compiler mode that needs to interoperate with everything else is inevitably going to be a challenge. This isn't the case with Svelte. While both runes and non-runes mode will be supported for the next two major versions, meaning there will be some short term fragmentation, we've made it clear that runes are the future of Svelte.
- EvanYou 3y ago> $state and $ref are quite different. I wouldn't say they are "different" - they are fundamentally the same thing: compiler-enabled reactive variables backed by runtime signals! But yes, Vue already exposes the underlying concept of refs, so for users it's two layers of abstractions. This is something that Svelte doesn't suffer from at this moment, but I suspect you will soon see users reinventing the same primitive in userland. > There's strict read/write separation I'd argue this is something made more important than it seems to be - we've hardly seen real issues caused by this in real world cases, and you can enforce separation if you want to. > We're instead encouraging people to use familiar JavaScript concepts like functions and accessors This is good (despite making exposing state much more verbose). In Vue, we had to introduce destructuring macros because we wanted the transform to be using the same return shape with all the existing composable functions like VueUse. > There are already a lot of different ways to work with Vue This is largely because Vue has a longer history, more legacy users that we have to cater to, so it's much harder to get rid of old cruft. We also support cases that Svelte doesn't account for, e.g. use without a compile step. That said, the default way with a compile step is now clearly Composition API + <script setup>. Reactivity Transform also only really applied in this case so the point you raised is kinda moot. Separate from the above points, the main reason Reactivity Transform wasn't accepted remains in Runes: the fact that compiler-magic now invades normal JS/TS files and alters vanilla semantics. Variable assignments can now potentially be reactive - but there is no obvious indication other than the declaration site. We had users trying Reactivity Transform on large production codebases, and they ended up finding their large composition functions harder to grasp due to exactly this (and not any of the points raised above).
- Exuma 3y agoBased Vue