Scale your Frontend application with Module Federation

 Luca Del Puppo 

Luca Del Puppo

  • Senior Software Developer
  • JavaScript enthusiast
  • TypeScript lover
  • “Youtuber”
  • “Writer”

Love sport: running, hiking

Love animals

Why are we here?_

Backend

Frontend

Backend

Backend

Why do we need to scale?_

  • Increasing business
  • Increasing team -> multiple teams

Context

Context

Context

Context

Context

What are

Micro Frontends?_

Micro Frontend is a type of architecture in which a web application is divided into different modules or individual functions, implemented autonomously.

 

This allows frontend teams the same flexibility and speed that microservices provide backend teams.

Micro Frontends Principles_

  • Modelling around business domain
  • Decentralisation
  • Culture of automation
  • Deploy independently
  • Hide implementation details
  • Isolate failure

Decisions Framework_

Key MFEs decisions_

  1. Define
  2. Compose
  3. Route
  4. Communicate

Definition_

Header

Footer

Wall

Ads

Requests

Landing

Sign in
Sign up

Catalog

Composition_

ORIGIN

CDN

CLIENT

Routing_

ORIGIN

CDN

CLIENT

R

R

R

R

Communication_

Header

Wall

Ads

Requests

Footer

Header

Wall

Ads

Requests

Footer

WebStorage / Cookies

Query String

Other challenges_

  1. Sharing code and components
  2. Design consistency
  3. Technology agnostic
  4. Dependency management
  5. Organization Impact

Hello Module Federation_

Module Federation is an architectural pattern for the decentralization of JavaScript applications. It allows you to share code and resources among multiple JavaScript applications (or MFE).

This can help you:

  • Reduce code duplication
  • Improve code maintainability
  • Lower the overall size of your applications
  • Enhance the performance of your applications

Features_

  • ⚡ Code sharing & Dependency reuse

  • 📝 Manifest

  • 🎨 Module Federation Runtime

  • 🧩 Runtime Plugins System

  • 🚀 Dynamic type prompt

  • 🛠️ Chrome Devtool

  • 🦀 Rspack and Webpack Support

Actors_

  • Producer (Remote)

  • Consumer (Host)

Producer_

An application that exposes other modules to be consumed by other JavaScript applications through the Module Federation build plugin with the exposes configuration is referred to as a Provider (Producer) in Module Federation.

A Producer can also act as a Consumer.

// rsbuild.config.ts
import { defineConfig } from '@rsbuild/core';
import { pluginReact } from '@rsbuild/plugin-react';
import { ModuleFederationPlugin } from '@module-federation/enhanced/rspack';

export default defineConfig({
  server: {
    port: 3000,
  },
  dev: {
    // It is necessary to configure assetPrefix, and in the production environment, you need to configure output.assetPrefix
    assetPrefix: 'http://localhost:3000',
  },
  tools: {
    rspack: (config, { appendPlugins }) => {
      // You need to set a unique value that is not equal to other applications
      config.output!.uniqueName = 'federation_provider';
      appendPlugins([
        new ModuleFederationPlugin({
          name: 'federation_provider',
          exposes: {
            './button': './src/button.tsx',
          },
          shared: ['react', 'react-dom'],
        }),
      ]);
    },
  },
  plugins: [pluginReact()],
});

Consumer_

An application that consumes modules from other Producers through the Module Federation build plugin with the remotes configuration is referred to as a Consumer (Consumer). A Consumer can also act as a Producer.

// rsbuild.config.ts
import { defineConfig } from '@rsbuild/core';
import { pluginReact } from '@rsbuild/plugin-react';
import { ModuleFederationPlugin } from '@module-federation/enhanced/rspack';

export default defineConfig({
  server: {
    port: 2000,
  },
  tools: {
    rspack: (config, { appendPlugins }) => {
      appendPlugins([
        new ModuleFederationPlugin({
          name: 'federation_consumer',
          remotes: {
            federation_provider:
              'federation_provider@http://localhost:3000/mf-manifest.json',
          },
          shared: ['react', 'react-dom'],
        }),
      ]);
    },
  },
  plugins: [pluginReact()],
});

Share deps_

  • Singleton
  • Required Version
  • Eager
new ModuleFederationPlugin({
  name: '@demo/button',
  shared: {
    react: {
      singleton: true,
      requiredVersion: '~18.2.0',
      eager: true,
    },
  },
  //...
});

How to use them_

import './App.css';
// The remote component provided by federation_provider
import ProviderButton from 'federation_provider/button';

const App = () => {
  return (
    <div className="content">
      <h1>Rsbuild with React</h1>
      <p>Start building amazing things with Rsbuild.</p>
      <div>
        <ProviderButton />
      </div>
    </div>
  );
};

export default App;

Bundlers_

  • Webpack

  • Rspack

  • Rsbuild

Conclusion_

  • It is possible to think like Micro Services also in the Browser
  • Different ways to build MFEs
  • Module Federation is one of the most famous
  • Allow you to have independent builds
  • Share modules between builds
  • Async loading of the Federated modules
  • Work well with poly-repo and mono-repo

About this presentation_

About demo_

Resources_

Luca Del Puppo

@puppo92

Luca Del Puppo

Puppo_92

@puppo

We are hiring

Thank you!_