Have a large-scale UI that takes too much time to rebuild? Or own several teams that frequently run into code conflicts and other integration complications? – micro-frontend technology can play quite a significant role here.
A key reason behind the effectiveness of micro-frontend technology is the fact that it enables the coexistence of different front-end frameworks. It does this despite the dynamic nature of web applications – something micro-services could not keep up with.
A framework that further empowers Micro Frontends is Angular. This robust frontend tool, supplies components that assist you to write easy-to-use, readable, and maintainable code. Resulting in – ease of web development.
What are micro-frontends?
Micro-frontend refers to the small applications mostly divided by functionality working together as large applications. These are usually thought of as a composition of independent frontend sections/projects that occur at runtime, either on the server or on the client-side.
When to use this architecture?
In my opinion, one of the best methods of splitting an application is to split it into individual sets of screens and features. For instance, if you think about your mobile phone, you have different apps with distinctive features to serve various requirements. These apps often work together, but since they have a different purpose, they are implemented separately.
The micro-frontend technology facilitates a cross-functional approach. This allows different teams with distinct specializations to develop end-to-end features that may range from database to user interface. The resulting product/application is less bulky and more user-friendly.
Why choose a micro-frontend for application development?
Below are a few key reasons I believe why micro-frontends are valuable for large-scale development processes.
#1 Ease of upgrades
This approach builds strictly bounded contexts in the applications. This causes applications to be updated in a more incremental and isolated fashion without the risks of breaking up another part of the application.
#2 Faster project building
The larger a project, the longer it takes to build. By splitting your app into several smaller projects, each having its own build pipeline, it becomes easier and less time-consuming. Additionally, the continuous integration system also benefits from this as each project can be built and parallelized independently. Thus, finally concatenated together at the end to provide a large project.
#3 Deploying features dynamically
I think this is one of the best features of micro-frontends – deploying new features without the need to recompile anything else (not even runtime). If you already own an existing system, you will not be required to ship and re-install an entire system, rather you only need to do it for the newest features.
This is not only incredibly powerful but also opens up many new distribution possibilities.
#4 Parallelizing development processes
By splitting the UI into several independent projects, you open the chances of multiple teams working on the UI. Now, each team can handle one feature of the system simultaneously. For instance, if one team is working on the web app, another can work on the phone app, while another team can work on the contacts app, and so on. This way, each team gets to have their own Git repositories, run deployments whenever they want, and have their own changelogs and versioning.
For the most part, the teams are independent of each other. However, there still exists the need for integration between the apps. To do this, each team is required to define and guarantee backward compatibility on a public API (which is typically implemented through the use of the URL).
#5 Autonomous deployment
This is the major benefit of using micro-frontend technology. Reducing the scope of every individual deployment helps to mitigate the risks associated with the processes. Every independent section has its own continuous delivery pipeline, which supports its building, testing, and deployment significantly.
The independent nature of this architecture allows micro-frontends to follow the deployment journey autonomously, without taking into consideration the status of other pipelines and codes.
Defining the implementation approaches
You can easily implement micro-frontend with different approaches – by using single-spa and front.js frameworks or by using the @angular-architects/module-federation package.
For this article, I am going to implement a micro-frontend with – Angular.
How to get started (using Angular)?
To get started, we need an Angular CLI version supporting web pack 5. We can use both yarn & npm as package managers to accomplish this. Now create a project with different apps & configure the apps to run separately at different ports.
Now configure module federation-
1. Install @angular-architects/module-federation into the shell and the micro frontend by using the following commands:
ng add @angular-architects/module-federation --project host --port 5000
ng add @angular-architects/module-federation --project mfe1 --port 4200
The above command will generate two files webpack.config.js and webpack.prod.config.js with a skeleton of a module federation configuration for the apps.
The Module Federation includes the following options:
- name: Used as the entry file name if filename is not set.
- library: For assigning the output of the build into the variable mfe1.
- Filename: This is the specialized name of the entry file.
- exposes: The option exposes the component for consumption by other apps.
- shared: Is imported if the consumer app doesn’t have it.
2. Open the generated configuration file mfe1\webpack.config.js. and adjust exposes as required for example:
3. Now open the generated configuration file host\webpack.config.js. and adjust remotes as required for example:
4. Open shell/src/app/app-routing.module.ts and add a route to the micro-app.
loadChildren: () => import('mfe1/SettingModule).then(m => m.SettingModule)
And URL mfe1/flights.module does not exist at compile-time, ease the TypeScript compiler by adding the following line to the file host\src\decl.d.ts:
declare module ‘mfe1/SettingModule;
And then run two apps at the same time in two terminals using-
ng serve host –port 5000
ng serve mfe1 –port 3000
5. Follow the mentioned steps to load dynamically:
a. Open the host/src/webpack.config.json file and remove the registered remotes.
b. Open host/src/app/app-routing.module.ts and loadREmoteModule Function instead of import statement.
c. Restart both projects and we are still able to load the micro-app.
The latest version of Angular came into play on 12th May and is currently accessible as a production release on GitHub. This version draws nearer to an “Ivy all over” vision for the structure and is portrayed as a cutting-edge gathering and delivering pipeline, offering quicker AOT compilation.
Modernizing legacy application in a nutshell
I believe moving to a micro-frontend approach sets the right direction, as applications get bigger and velocity gets smaller. Here are a few key takeaways from the blog –
- Individual applications can be updated or modified without bothering the entire project (or other applications).
- Each project can be built and parallelized independently, making it easier for developers and less time-consuming.
- New features can be deployed without the need to recompile anything else (not even runtime).
- Each feature of the system can be handled independently by the team.
- Reducing the scope of every individual deployment helps to mitigate the risks associated with the processes.