Architect a large scale Vue.js Application
When starting a new application , the common challenge for an architect or developer are:
- how to structure the application as modular, flexible and scalable,
- how to handle http calls,
- how to do state management,
- how to add exception handling,
- how to add logging,
I always had these challenges and after researching around the community, I prepared a boilerplate which solves these problems and gives a way to write modular, flexible and scalable Vue.js application. I thought, I should write a series of article around this and this is the first part in which I am going to explain about the structure of application.
Thanks to Vue CLI 3 for the initial setup with zero configuration. But the initial setup doesn’t solve the above problems. I always try to design my front-end application into 3 layers:
- UI layer — Application UI components
- Business layer — Contains the application business logics, we often called them as services
- Application state — Application state management
Researching around the community, I found various ways to arrange the files in the project such as folder-by-type and folder-by-feature. I took an idea from these and created a folder structure which suits my need and it is similar to folder-by-feature as shown below.
On the root level, these will be folders/files created with Vue CLI. In addition to these, I added environments files (
.env.production) as recommended by Vue CLI for managing the different environments configurations in the application.
src folder, there is an
app folder which contains the main source code for the application and in addition, there will be
contains the static assets/images.
environment.js file. We can access environment variables using global
process.env but this is error-prone. So, I think, there should be common
interface through which we can access/limit the access of environment variables.
This will contains the Vue plugins.
This file is responsible for bootstrapping the Vue application.
app folder, we will be having the folder by feature. It will also contain a
shared folder, which will have application level shared
services etc. Apart from these,
app folder will contain 3 more files:
This file will be responsible for combining all the route configuration from feature modules (dividing app into features, I am calling them as feature modules). It will also have some app level routes such as wild-card routes.
All the state management related configuration will be done in this file. For eg.
Vuex related configuration will be done here. All the states from the different feature modules will be combined here and will be configured with the state management system.
This is the root component which will contain the main view of the application.
Application folder structure is divided based on the features and basically, that feature is called as feature module. Root of the feature module will be having the components along with their test and a
shared folder. Each feature module will also be having its
main component file. For eg. In
user feature module,
user-item are components,
user-routes.js contains the user feature module
user-state.js will combine the all user states and
user.vue is the main component of the user feature module.
One shared folder will be on app level and each feature module will also have their own shared folder. The key difference between them is that, app level shared folder will contain the application level shared things and module level shared folder will contain the module level shared things.
This folder will contain the shared components. The components which will be shared into different feature modules or components. For eg. Header, Footer, Navigation etc.
This folder will contain the configuration such as
api related config, configuration constants etc.
This folder will contain the shared directives. App level shared folder will contain the app level shared directives and module level shared folder will have the module level shared directives.
This folder will contain the shared filters. App level shared filters will be in app level shared folder and module level shared filters will be in module shared folder.
Most of the people are confused with the services. In simple terms,
services will contain the business logic or utilities or http calls that is independent of UI logic. Most people call them
services. I just called them as
App level shared folder will contain the state that will be sharable between different feature modules. Feature module level shared folder will have feature module state. The main reason of having app level shared state is that, let’s suppose, we will be implementing the lazy loading and put all the state of the application into feature modules. Suppose there is a part of state that is sharable into multiple feature module, then, it will not be available to other feature module if that particular feature modular is not loaded which is the owner of the state. To solve such type of problems, these kind of states will be a part of app shared state not feature state. So, that’s why, feature module will be having state that will be sharable into that feature module and app level shared state will be a part of app shared state.
I prepared the boilerplate around this architecture. You can find it here https://github.com/arunredhu/vuejs_boilerplate. I look forward to see your contribution.
At last, I am not saying, it will solve all problems, but this is the folder structure which solves many of my problems and as always said folder structure never freezes, things always needs to be refactored when the size and complexity of the project increase.