multinet-app / multinet-client

Multinet web client application
https://multinet-app.readthedocs.io
4 stars 3 forks source link

Add VueX to manage application-wide state #37

Closed waxlamp closed 4 years ago

waxlamp commented 4 years ago

@AlmightyYakob: @subdavis gained some insight into the use of VueX as the Vue conference he attended last week. We should pull him into a discussion about our use case and see what recommendations he might have for us.

subdavis commented 4 years ago

Since ya'll are already using TS, I would kind of like to see how a Vuex-lite would work here.

I found this article, which gives a really simple overview of the concept: https://dev.to/cooperaustinj/using-vue-observable-as-a-state-store-37fa

I probably wouldn't follow that style though. You could separate your action functions out into its own file and have the full power of typescript.

waxlamp commented 4 years ago

Since ya'll are already using TS, I would kind of like to see how a Vuex-lite would work here.

I found this article, which gives a really simple overview of the concept: https://dev.to/cooperaustinj/using-vue-observable-as-a-state-store-37fa

This looks like a really interesting approach. Are the main reasons to do it this way to (1) avoid the full complexity of VueX and (2) get full TS support?

I probably wouldn't follow that style though. You could separate your action functions out into its own file and have the full power of typescript.

Does doing it the blog post way prevent you from getting full TS support? Would you instead define functions in a file, then re-export those into an object from a top-level file, so you sort of implicitly have a version of VueX namespaces?

And on a broader note: do you think that following this approach could have its own pitfalls in terms of not following the standard approach of just using VueX? In my opinion, not having full TS support is a big loss, but that needs to be balanced against the risk of doing things in an uncharted way. This "Vuex-lite" approach seems simple enough that the risk seems small to me, but I'm curious what you think.

Thanks @subdavis!

subdavis commented 4 years ago

Does doing it the blog post way prevent you from getting full TS support?

Oh no you're right. That style would be fine. I suppose the only significant difference between that style and individual functions is that each component could import exactly the functions it cares about. I sort of like that anyway, because removing or modifying function names will be build-time errors whether you typescript or not.

Are the main reasons to do it this way to (1) avoid the full complexity of VueX and (2) get full TS support?

That's what I'm expecting.

And on a broader note: do you think that following this approach could have its own pitfalls in terms of not following the standard approach of just using VueX? In my opinion, not having full TS support is a big loss, but that needs to be balanced against the risk of doing things in an uncharted way. This "Vuex-lite" approach seems simple enough that the risk seems small to me, but I'm curious what you think.

I totally agree that we should stop and think before we do non-standard stuff. However, I've also never come away from using vuex feeling like "I'm glad I did it that way". It usually just feels like I went to a ton of extra trouble and all did was befuddle intellisense.

I've decided to try this vuex-lite on a small, inconsequential client for DIVA. I'd love to share it with everyone once it's ready.

subdavis commented 4 years ago

Here's a sneak preview. It's exactly what you're expecting. https://gitlab.com/diva-mturk/stumpf-diva/-/merge_requests/133/diffs#diff-content-870db12d07e5dae908d9e7fa78fc7ff573ce2819

waxlamp commented 4 years ago

This is really interesting, Brandon. You could even do "namespaces" by defining other store slices in other modules, import those at top level and smash them into the global store object. That might be more trouble than it's worth but there seems to be a path.

The only thing I would miss from the traditional VueX approach is the constraint about when and how you commit mutations or call getters, etc. In the Redux days, one common approach was to make use of ImmutableJS, which provided the same safeties by semantically forbidding in-place mutation of the data structures. This is more tradeoff consideration between full TS support and footgun possibilities.

Do you know if Vue 3.0 is planning to fix the TS deficiencies in VueX, in the same way that the composition API aims to do?

jjnesbitt commented 4 years ago

That article you linked is interesting @subdavis. Regarding Vuex-lite vs Vuex, I think we might actually benefit from full Vuex functionality, as one of the main areas we can improve the codebase is through using actions to update the state, as currently we're calling a self defined update function in several different components, which make api calls. With that in mind though, I'm not sure what the better approach would be, Vue.observable vs Vuex. I suppose if Vuex is lacking typescript support, using Vue.observable would make more sense.

waxlamp commented 4 years ago

I'd say we should do a careful "research spike" with Vue.observable()--maybe prototype out a bit of state management that could replace some of those update() calls, and then take a step back and see how we like it. I'm pretty committed to having good typescript support, and I think that is probably more valuable than using VueX for VueX's sake.

We may also want to do a bit of research into how typescript fanatics deal with VueX as well.

subdavis commented 4 years ago

We may also want to do a bit of research into how typescript fanatics deal with VueX as well.

I'm basing some of my opinions on https://github.com/politico/typesafe-vuex and discussions with the people who made that. It looks painful, and they say it's painful. But maybe we would have a different experience.

waxlamp commented 4 years ago

I would not have guessed "Politico" if you asked me which organization is sounding the alarm for typesafe VueX :joy:

Another cost to consider: if we don't use VueX, that means we won't be able to track state changes using the Vue debugger / browser extension.

waxlamp commented 4 years ago

Just a note for @subdavis: we decided to go with direct-vuex because we didn't want to give up the Vue debugger support, community support around VueX (such as it is), and the direct-vuex approach looked like a nice balance of traditional VueX+ecosystem, and type safety.

@AlmightyYakob, may present the associated PR (#68) at the next frontend discussion.

subdavis commented 4 years ago

Oooh, looking forward to it. Thanks for the heads up.