Micro-Frontends with Zephyr - The Complete Guide

Micro-Frontends' configuration and deployment processes are known to be complicated and painful to debug. Zephyr Cloud not only to helps with resolving dynamic URL and development process for applications applying Micro-Frontends architecture, but also deployment, versioning and more. This section will walk through the necessary configuration to ensure you have a smooth development workflow and deployment process.

Checklist

Micro-Frontends Configuration

We have first class support for a Micro-Frontends architecture based on Module Federation. Other Micro-Frontends architectures may already work or will be supported in the future.

An example working shell app's configuration can be seen below as well as in our example repository

rspack.config.js
1new ModuleFederationPluginV1({
2      name: 'app_01',
3      filename: 'remoteEntry.js',
4      remotes: {
5        app_02: 'app_02@http://localhost:3002/remoteEntry.js',
6        app_03: 'app_03@http://localhost:3003/remoteEntry.js',
7        app_04: 'app_04@http://localhost:3004/remoteEntry.js',
8        app_05: 'app_05@http://localhost:3005/remoteEntry.js',
9      },
10      exposes: {
11        './SideNav': './src/SideNav',
12        './Page': './src/Page',
13      },
14      shared: {
15        ...deps,
16        '@material-ui/core': {
17          singleton: true,
18        },
19        'react-router-dom': {
20          singleton: true,
21        },
22        'react-dom': {
23          singleton: true,
24        },
25        react: {
26          singleton: true,
27        },
28      },
29    }),

Build remotes first

At the moment. when we are resolving your remote dependencies, we will need the remotes to be built first. Be wary that the first built remotes should not be consuming any other remotes.

In the example below where you have one shell and one remote, you will need to build the remote first.

mf_1_circular_dependencies

Let's take a look at another example. You have a shell application, within the shell app you have two modules: HeaderNav and TaskContent.

mf_2_circular_dependencies

The HeaderNav exposes Logo, UserProfileInfo and LeftNav.

The TaskContent exposes SearchBar.

In this scenario, LeftNav is consumed by TaskContent; SearchBar is consumed by HeaderNav.

You will need to build either the TaskContent or the HeaderNav first, comment out the remotes that have yet built and add them back later.

package.json name and Module Federation config

Make sure your remotes' package.json name field is exactly the same as your Module Federation Configurations like so:

package.json from your first remote app
1name: 'post'
package.json from your second remote app
1// Your first remote's package.json 
2name: 'follow'
Module Federation config in your host
1`remotes: ['post', follow']`

You may refer to how each zephyr options were resolved here

Git repository

Several details related to git are required to have a successful deployment.

  • Project directory must be a git repository
  • Current project directory must have a branch
  • Current project must have created a commit

Confirm access right

Do you have the admin or editor access to the application you are trying to deploy? You can check it on Zephyr Dashboard.

If you don't have it yet, you can contact your Admin on Zephyr dashboard to invite you and set up the correct access right.

Zephyr Options

Although we resolve your application's configuration, git, package.json information to understand your application's deployment information and details, you can also opt to pass in configuration directly.

Directory location

Some options are resolved based on where bundler locates so be mindful about hoisting dependencies or not having a package.json in each application when you try to deploy an application through Zephyr - especially when you are deploying Micro-Frontend applications.

Each options is resolved like so, take create-nx-workspace-mf's shell app as an example:

ZephyrOptions
1const zephyrOptions = {
2
3    /** General application configuration details */
4    app: {
5
6    /** This would match your git's organization name. If you haven't create an organization on Zephyr dashboard yet, the organization would be auto-created based on your git repository's owner name - could be your organization's name or your personal git profile's name depending on the repository. */
7    org: 'ZephyrCloudIO', 
8
9    /** This would match your repository's name. Hence your project folder would need to be initialized as a git repository. */
10    project: 'zephyr-examples', 
11
12    /** This would be resolved from your package.json's name. */
13    name: 'shell', 
14
15    /** This would be resolved from your package.json's version. */
16    version: '0.0.0'
17    }, 
18
19    /** Micro-Frontends configuration. If you have a Module Federation configuration in your bundler config - this is how we resolve each field. Otherwise this field would be empty. */
20    mfConfig: {
21
22        /** The name field in your Module Federation configuration. */
23        name: 'shell', 
24
25        /** The filename in your Module Federation configuration. Default to `remoteEntry.js`. */
26        filename: null, 
27
28        /** The `exposes` field in Module Federation configuration. */
29        exposes: null, 
30        
31        /** The `remotes` field in Module Federation configuration. */
32        remotes: ['remote1', 'remote2'], 
33
34        /** The `shared` field in Module Federation configuration. */
35        shared: null,
36    }
37}