Skip to content

Latest commit

 

History

History
150 lines (108 loc) · 4.61 KB

microfrontend-setup.md

File metadata and controls

150 lines (108 loc) · 4.61 KB

Microfrontend Setup

This microfrontend setup is configured to have this project acting as the remote.

It is responsible to export the children modules/app which will be loaded at runtime and will be provided with some context e.g. auth, routing.

microfrontend-shell-boilerplate is a default remote (child) boilerplate meant to be consumed by a host such as microfrontend-shell-boilerplate.

Isolation And Defined Boundary

Choosing a Unique Name

It's important to note the remote has to use a unique name in order to work and not collide with other sibling remotes.

The suggested practice is use such name as:

  • Git repository
  • Webpack Module Federation configuration
  • Module (package.json) name
  • CSS wrapper name

Custom Redux Context

The Redux store needs to be isolated and non accessible by the host or by the sibling remotes.

For such reason, the store module (src/store) exports a custom React Context that is used in the Redux / React-Router Provider components.

import configureStore, { ReduxContext } from './store';
///
///
function ExportableApp({ ...propsFromTheHost, }) {
  return (
    <Provider store={store} context={ReduxContext}>
      <App {...propsFromTheHost} />
    </Provider>
  );
}

Note While it's not necessary to use Redux in the remote, it's still quite convenient to separate React from the application flow and business logic.

You can choose to adopt a different state manager as long as you keep it isolated and do not allow the children applications to access it.

CSS Namespacing

Due to the nature of the architecture, it's not possible to eliminate the issue of classnames collision.

However, it's important note that the whole microfrontend modules should be wrapped into a single, high-order, unique classname in order to reduce or even eliminate CSS naming collision.

function ExportableModule() {
  return (
    <div className="uniquely-chosen-remote-name">
      <div classNam="header"> ... </div>
      <div classNam="body"> ... </div>
      <div classNam="footer"> ... </div>
    </div>
  );
}

And defined the style accordingly in SCSS (CSS can work too)

.uniquely-chosen-remote-name {
  .header {
    // css rules
  }
  .body {
    // css rules
  }
  .footer {
    // css rules
  }
}

Webpack Module Federation

The default configuration works when running the host locally, however it's necessary to adjust the settings before deploying online.

In the project root directory you can find the webpack.config.js configuration file.

Code Splitting

Code splitting is automatically enabled when using the ModuleFederationPlugin.

Module Federation Plugin

At the webpack.config.js plugins section, you can find the ModuleFederationPlugin.

The configuration is similar to the following:

plugins: [
    new ModuleFederationPlugin({
      // Preferable to use a unique name and filename when
      // several remotes are being consumed
      name: 'app',
      library: { type: 'var', name: 'app' },
      filename: 'app.js',
      // Specify and expose components to be consumed
      exposes: {
        './App': './src/Injector',
        './Menu': './src/Menu',
      },
      shared: [
        'react',
        'react-dom',
        ...
      ],
      ...

In the expose configuration, you need to export all the components you expect are going to be use.

Note - export only the modules

Make sure you do not export the bootstrap.tsx as that is only used locally. When your modules are imported by a host, they do not need to include all the traditional context setup specified in bootstrap.tsx since the host will be providing that.

Note - set a unique name

Make sure you set the unique name in the following fields:

  • ModuleFederationPlugin.name
  • ModuleFederationPlugin.library.name
  • ModuleFederationPlugin.filename

Resources