Working on various SPA projects, I noticed that I often have to do the same actions repeatedly. We repeatedly connect the same libraries, make familiar configurations, establish the known application structure, and create similar modules. I decided to optimize this process and created a foundation for a large SPA using Laravel and Vue3.
In this article, I will share my perspective on the SPA structure using Laravel and Vue.js. We will design and establish the application architecture to make it flexible and scalable from the outset. Later, we will select the appropriate libraries to use throughout the development process. We will create CRUD and lay down modularity suitable for developing various CRMs.
I want this application to meet the following criteria:
- Reduce project maintenance time and code navigation
- Reduce the start project time
- Avoid high cohesion between modules
- Be understandable for programmers with little experience
- Help avoid code duplication
- Be easily extensible
- Lay the groundwork for writing high-quality code in the future
To make life easier and not get lost in the project, it is necessary to structure it correctly. Initially, the application should be divided into responsibility levels, such as user interface, database, and business logic.
Next, each layer should be divided first by functionality - these will be separate modules. And then the code of each module should be divided into files according to the chosen pattern.
Inspired by the DDD philosophy, I decided to divide both the front-end and back-end into semantic modules. But these are not classical domains described by Evans. His model is also not ideal. In any application, there are always relationships between components — relationships between models.
Backend models will remain a separate layer because they duplicate the database with all its relationships.
Let's move into the module the files we always create when developing new functionality. These are routes, controllers, request classes, and resource classes.
{ModuleName}/
│
|── routes_api.php
│
|── Controllers/
| |
│ └── {ModuleName}Controller.php
│
|── Requests/
| |
│ └── {ModuleName}Request.php
|
|── Resources/
|
└── {ModuleName}Resource.php
Other design patterns like events, jobs, policies, etc., are used less frequently, and you can decide whether to keep them as a separate layer or include them in modules.
We will also build the frontend part following this modular logic. The structure of one module will be as follows:
{moduleName}/
│
├── routes.js
│
|── {moduleName}Api.js
│
|── {moduleName}Store.js
│
|── components/
|── {ModuleName}List.vue
|── {ModuleName}View.vue
└── {ModuleName}Form.vue
The module will contain a routes.js
file, {moduleName}Api.js
- a file where all promises and backend calls will be located. {moduleName}Store.js
- a separate file will host the Store, where actions, getters, and other application state variables will be located. And we will need a folder with components. All of this should be connected automatically without unnecessary movements. All manipulations with dynamically loading modules are done to minimize coupling between them. This allows adding and removing modules without consequences.
I will explain how all of this works in the next articles, and for now, I leave a link to the ready-made groundwork here. This project also has its own module generator, which will create all necessary files for you.
https://github.com/Yurich84/laravel-vue3-spa
I will describe this project in more detail in my next article.
Top comments (0)