Micro frontends without JavaScript components

by Mihael Haluga, February 7th, 2020

Ever since the microservices pattern took the web development by storm, it was inevitable that it would be applied to the frontend development as well - in a form of micro frontends. The idea was to create your web interface in such a way that any segment (no matter how granular) can be deployed and developed separately.

Wrapper application (pictured above) in this case is responsible for fetching HTML segments served by separate microservices. Most development teams prefer to use the latest technologies in frontend development so they end up building these segments in React, Vue.js or Angular (or any combination of these). This decision usually results in a complex build process which becomes even more challenging if you allow free reign over the development of a single JavaScript component. Development complexity is something that microservices and micro frontends patterns try to mitigate in an attempt to move away from the monolithic application structure. Without recognizing this danger upfront, development turnaround time will suffer because of the longer build times, the need to maintain too many JavaScript codebases (which can potentially be very different in case the project ends up using more than one JavaScript framework) and by steeper learning curve for new team members.

This is something we became aware of when we took over the development of a monolithic application inherited from the previous development team. The main reasons for refactoring the application into a more maintainable and manageable number of microservices were:

  • long application deployment time (which prevented application deployments during client work hours) and
  • long developer onboarding time (it took months before new team members would become productive).

Taking into account that this application was not publicly accessible we did not have to worry about SEO - all of the focus was put on the functionality of the interface itself. We realized we could solve the aforementioned issues by introducing a set of limitations in a way that would still allow us to build a fast, user-friendly and functional interface.

Self-imposed limitations

The first thing we decided on was to avoid reinventing the wheel by creating our own CSS and JavaScript frameworks. There’s a lot of existing CSS and JavaScript frameworks out there that you can easily use. You don’t even have to take care of building them locally or on your server as they are conveniently served from fast CDNs.

Wrapper application is responsible for holding all the CSS and JavaScript links that the framework of choice ships with. It works as a router and a mapper of the segments per application route. It also holds all the custom JavaScript code needed for fetching individual segments or making API calls.

Each of the microservices returns only static blocks of HTML. To change the look and feel of each block, microservice can include (scoped) style tag that holds any custom CSS. Keeping blocks simple and static makes testing much more manageable.

Taking advantage of the browser’s default behavior and the fact servers can shift some of the burdens from the client-side was a must. The browser recognizes the style tag automatically when inserted into the DOM and applies it to the page. Query strings can be used to store data between page requests, form submissions and communication between individual segments on the page.

Keeping JavaScript away from the components meant that developers were challenged to employ creative thinking about the UI they were building. Like using the fact that form submits can change the state of the UI (that is, defer state change to the server) or just by keeping things simple, for example, by using the default browser date picker input element.

Single pages should not hold a large number of forms because with this approach communication among them is limited. This can be solved by creating multi-step forms that can move in both directions while being careful not to break the good user experience.

Utilizing these limitations, while applying the microservices pattern, the development process became much simpler without the need to juggle complex build processes. Newer recruits could join the regular development process much sooner and the number of development stacks has been significantly reduced compared to the old monolithic application structure.

About the author:
Mihael Haluga
Full Stack Developer
An avid reader of historical fiction, a retro gamer who can’t accept the always-on nature of modern games, a coder who likes to keep it simple and a rookie tech blogger.
Need help with implementing micro frontends without JavaScript components? Contact us!