When looking at Vuex tutorials, you can see most of them are quite simple.
The logic is explained well, but scalability suffers. How will this work in my production app?
Here’s a simple store example from Vuex official docs:
There’s no need to explain this. I assume that you already have some Vue and Vuex knowledge prior to this article.
My goal is not to explain what a store, state, or mutations are.
Instead, I want to show you a massive store with 1,000+ state attributes, mutations, actions, and getters.
I want to teach you how to structure the store for the best maintainability, readability, and reusability.
It can have 100,000+ attributes. It would still be clear.
Let’s dive in.
As we already said, keeping everything in one file will create a mess. You don’t want a 50,000+ LOC file. It’s the same as keeping your app in one component.
Vuex helps us here by dividing the store into modules.
For the purpose of this example, I will create a store with two modules. Note that the process is the same for 100+ modules, as well as 100+ actions, getters, and mutations within every module.
namespaced attribute is incredibly important here. Without it, actions, mutations, and getters would still be registered at the global namespace.
namespaced attribute set to true, we divide actions, mutations, and getters into the modules as well.
This is really helpful if you have two actions with the same name. Having them in a global namespace would create clashes.
As you can see, the module is completely “local” right now. We can access it only through the user object on the state.
Exactly what we want for our massive application.
Cool, now we have a store divided into modules!
However, I don’t like the hardcoded strings for actions. It’s definitely not maintainable. Let’s address this issue.
We don’t just want to access every property from every module in every file. That sentence sounds like hell.
We want to import them first. Then use
mapMutations to achieve that.
This gives you a clear view of store attributes used by your Vue file.
But that’s not enough. Everything is still in one file. Let’s see what we can do to scale it properly.
Ideally, we want to split modules into different folders. Within those modules, we want to split their mutations, actions, getters, state attributes, and types across different files.
store will be created in the root folder of our project.
It will contain two things:
Before explaining the
index.js file, let’s see how we divide a single module. Let’s check the
All of its actions, mutations, and getters should be listed in the
types.js file. So, something like:
We’ll have a clear view by importing those consts every time we want to use them.
Let’s look at the actions now. We want to move them to the
To do so, we only need to copy the
actions object within the module and
export default it, while importing the types:
We will do the same thing for mutations and getters. The state attributes will remain in
index.js (within the user module folder):
Now we have all of our modules divided into multiple files.
The one thing remaining is to link all those modules in the
index.js file within the
By using this architecture, we had zero problems with scalability in our massive production app.
Everything is so easy to find.
We know exactly where all the actions are triggered.
The system is highly maintainable.
If you have any recommendations for the improvements, please let me know. I would love to hear your opinion.