/ilc

Isomorphic Layout Composer - complete solution for Micro Frontends composition into SPA with SSR support

Primary LanguageJavaScriptApache License 2.0Apache-2.0

Isomorphic Layout Composer logo


Latest version Demo website Actions Status Docker Pulls Docker Pulls

Isomorphic Layout Composer (ILC) - layout service that compose a web page from fragment services. It supports client/server based page composition.

It's key difference and advantage against other solutions lays in the fact that it does page composition isomorphically. It means that page will be assembled at server side using apps that support server side rendering (SSR) and after that it will be hydrated at client side so all further navigation will be handled by client side rendering.

Such approach allows to combine advantages of the Micro Frontends, SPA & Server Side Rendering approaches.

This repository also contains an example of how you can create a front-end that is composed from multiple applications which work in concert and deliver unified experience.

Why do I need ILC?

Microservices get a lot of traction these days. They allow multiple teams to work independently from each other, choose their own technology stacks and establish their own release cycles. Unfortunately, frontend development hasn’t fully capitalized yet on the benefits that microservices offer. The common practice for building websites remains “the monolith”: a single frontend codebase that consumes multiple APIs.

What if we could have microservices on the frontend? This would allow frontend developers to work together with their backend counterparts on the same feature and independently deploy parts of the website — “fragments” such as Header, Product, and Footer. Bringing microservices to the frontend requires a layout service that composes a website out of fragments. ILC was developed to solve this need.

Key features

  • 📦 Based on single-spa & TailorX - battle tested solutions inside
  • 📱 Technology Agnostic - use it with React, Vue.js, Angular, etc...
  • ⚙️ Server Side Rendering support - key advantage over competitors
  • 🗄 Built-in registry - add new apps, pages or change configs and templates in few clicks. More info here.
  • ⚡️ Built for speed - server side part of the system adds just ~17ms of latency
  • 👨‍💻 Develop right at production - Doc
  • 💲 Baked by Namecheap - we use it internally and plan to evolve it together with community

🚀 Quick start

Check out demo website available online or go through the steps to spin it up locally:

  1. Clone this repository
  2. Run docker-compose up -d
  3. During first launch or shutdown only. Run docker-compose run registry npm run seed
  4. PROFIT 😎

More information about demo applications used in this quick start you can find here.

And don't miss the Step-By-Step lessons about apps development with ILC.

Architecture overview

ILC Architecture overview

Repo structure

|– ilc: code of the Isomorphic Layout Composer
|– registry: app that contains configuration used by ILC. Such as list of micro-fragments, routes, etc...

Further reading

🔌 Adapters

To conveniently connect various frameworks to ILC we rely on the ecosystem of the single-spa provided adapters. However sometimes we need to extend original ones to deliver better integration with ILC. Here are the list of the adapters that were forked & modified:

Notes

Why @portal/

We're using webpack (a static module bundler) to build each application for our micro-frontend approach. Webpack requires access to everything it needs to include in the bundle at build time. This means when an app that imports a service, for example planets importing the fetchWithCache service, webpack will try to bundle the service into the planets bundle. The built in way to avoid webpack doing this is webpack externals, using externals works really well but to avoid having to include a regex for each service I'm using the postfix to signal to webpack (and developers) that the import is another micro-app/service/front-end. The prefix isn't required if you would rather include a different postfix or none at all it should work, you'll just have to modify each webpack config for externals.

Code splitting

Code splitting is a complicated topic. I'm not going to dive into each facet of it within Webpack, see Webpacks docs for that.

In our project code splitting is further complicated because webpack's module format expects to load more modules from the website root, which will always fail in this project unless webpack is told where to load additional modules. Right now there is a single example of this, done in the people application.