Micro-frontend implementation [part 2] — Nested React apps

Tan Bui
3 min readDec 12, 2021

The previous article Micro-frontend implementation [part 1] — React in Angular uses Build time integration implementation, which is very common today. The child component (or container) can be installed as a npm library.

Pros:

  • The whole frontend code is packed in one single monolithic bundle, making it easy to run from localhost or e2e test.
  • Some validations (e.g. linter, dependency conflict) could be done in build time.

Cons:

  • The host project would be a huge package because it contains all dependencies of child components.
  • There is a tight coupling between the host and containers — which is the wrapper component. For example, if a container upgrades to a new version of React, the wrapper might not work.
  • There should be a versioning system for dependent components. When one releases a new version, the whole app needs to be updated and re-deployed with the new version as well.

Run time integration is another approach that loads the micro-frontend on demand, depending on the runtime context.

Server-side composition lets the backend decide which micro-frontend to load based on the request URL using e.g. reverse proxy of Nginx. This introduces tight coupling between frontend and backend that I’d try to avoid. (Reminding me back to the day PHP returns frontend content to the response… 👴).

In Client-side composition, the container app is built and deployed separately like a standalone app which is fully (the whole container app) or partly (some components of the container app) exposed as a remote package that the host app can fetch the needed parts. Since 10/10/2020, Webpack 5 Module Federation Plugin is a promising solution.

Pros:

  • The micro-frontend is completely de-coupled from the host application. As long as it ups and runs and exposes correct modules, the tech stack isn’t a matter.
  • A micro-frontend may only need to work with some specific micro-services, so they can be deployed in the same cluster.
  • Deployment is done independently. The host app doesn’t need any redeployments when a micro-frontend container is updated.

Cons:

  • The container must be running on a //host:port .

Some use cases to decide between build time or run time integrations:

  • Small components or groups of components that are usually reused in many places of the app: button, calendar, etc ➡️ build time
  • A complete feature that usually occupies the main content area of the app: login page, account page, order page, etc ➡️ run time

Example

The project below includes TypeScript React apps: host and container which are can be in different repositories. I put them all in one place just for convenience and easier to start them both with lerna .

Each project uses webpack instead of react-script . To make it simple, only development mode is used in this example project, a decent React + TS + Webpack starter project could be found here.

A simplewebpack.config.js for React/TS is:

To configure the Module Federation plugin, in the container webpack config, add this:

The plugin will bundle the exposing components (which is ./src/Counter here) to the route ./Counter as a remote package named container . The endpoint to access the package is remoteEntry.js . When this container app runs, the host app can access to this bundle via http://localhost:3002/remoteEntry.js.

In the host app config, add this:

new ModuleFederationPlugin({
name: "host",
remotes: {
container: "container@//localhost:3002/remoteEntry.js",
},
shared: ["react", "react-dom"],
}),

If the container Module Federation plugin name is name: myApp , then the remotes config will be myApp: "myApp@//localhost:3002/remoteEntry.js"`.

To use the remote Counter component, the host app can import it using:

const RemoteCounter = React.lazy(() => import("container/Counter"));
// ...
<RemoteCounter counter={count} onIncrease={() => setCount(count + 1)} />

State and event bindings work as usual.

Online demo: https://stackblitz.com/edit/module-federation-example.

Next: https://tanbt.medium.com/micro-frontend-implementation-part-3-angular-contains-react-using-webpack-5-module-federation-ddbd3f5f16cc

--

--

Tan Bui

Software Engineer @Smartly.io, phototaker, naturelover.