Nx has supported Module Federation for a long time now and its popularity is seeing year-on-year increase. It has proven to be the defacto solution for modern Micro Frontends and Nx has embraced this and helped developers scaffold projects that use Module Federation; offering the most scalable and the most developer friendly experience to do so. However, we have always taken a step back when it came to the final piece of the puzzle: Deployment.
Micro Frontends are, by their very nature, more complex to deploy. You are no longer deploying one build artifact but rather, many build artifacts that could even be on different release cadences from each other. And yet, we still expect the final application that our users interact with to be stable.
There are so many approaches to deployments - think Kubernetes, Storage Buckets with DNS, EC2 instances etc - that it has always been difficult for us to recommend a solution. That was until Zephyr Cloud entered the game.
Zephyr Cloud is a "bring your own cloud" deployment platform with best-in-class support for module federation projects that integrates right into your application build, providing seamless deployments without having to learn any new commands. With features such as:
- Auto-deployment on build
- Live Preview link generation
- Version rollback and roll-forward
- Micro Frontend dependency management
- A Chrome Extension to manage environments
- Support for a wide range of Cloud Platforms (such as Cloudflare and Netlify)
- A beautiful UI to visualize your deployments
And so much more, Zephyr Cloud really is one of the best deployment solutions available.
You can learn more about the full feature set that Zephyr Cloud offers here.
I myself, Colum Ferry, after having been allowed to experiment with it in its infancy back in February 2024 said
Zephyr Cloud is the Micro Frontend orchestration tool you never knew you needed. What they have built will change the deployments for the better. Think of the disruption k8s caused. Zephyr Cloud will do the same for the Micro Frontend world.
Reference: Linkedin
And I stand by that statement.
Therefore, in this article I'll show you how to set up React Module Federation with Nx and Rspack and how to integrate it with Zephyr Cloud for deployment.
Step 1: Set Up the Nx Workspace
We'll start by creating an empty Nx workspace:
~❯
npx create-nx-workspace myorg
1NX Let's create a new workspace [https://nx.dev/getting-started/intro]
2
3✔ Which stack do you want to use? · none
4✔ Package-based monorepo, integrated monorepo, or standalone project? · integrated
5✔ Which CI provider would you like to use? · github
6
7 NX Creating your v19.7.0 workspace.
8
9✔ Installing dependencies with npm
10✔ Successfully created the workspace: myorg.
11✔ Nx Cloud has been set up successfully
12✔ CI workflow has been generated successfully
13
14
Next, we'll want to navigate into our new workspace:
❯
cd myorg
And finally, we'll add the @nx/react
plugin to our workspace.
❯
npx nx add @nx/react
Step 2: Scaffold the Module Federation Projects
Now that we have the @nx/react
package installed, we have access to all the generators it offers. We'll use the host
generator now to scaffold out Module Federation projects.
If you'd like a more indepth recipe for scaffolding host
and remote
generators you can take a look through our Module Federation Recipes.
~/myorg❯
npx nx g @nx/react:host apps/shell --remotes=remote1 --bundler=rspack
1 NX Generating @nx/react:host
2
3✔ Which stylesheet format would you like to use? · css
4✔ Which E2E test runner would you like to use? · playwright
5Fetching prettier...
6Fetching @nx/rspack...
7Fetching @nx/playwright...
8Fetching @nx/jest...
9
10// REMOVED FOR BREVITY
11
12 NX 👀 View Details of shell
13
14Run "nx show project shell" to view details about this project.
15
16 NX 👀 View Details of remote1
17Run "nx show project remote1" to view details about this project.
18
With that, two applications will be added to our workspace shell
and remote
as well as their counterpart e2e projects.
These projects contain all the usual tasks you would expect to see with a Nx project such as build
, serve
, test
, lint
. You can learn more about Running Tasks in Nx here.
We specified --bundler=rspack
indicating that the applications should be built with Rspack.
This support has been newly added to Nx since Nx 19.7.0.
You'll note the shell/rspack.config.ts
file. It's contents should match the following:
1import { composePlugins, withNx, withReact } from '@nx/rspack';
2import {
3 withModuleFederation,
4 ModuleFederationConfig,
5} from '@nx/rspack/module-federation';
6
7import baseConfig from './module-federation.config';
8
9const config: ModuleFederationConfig = {
10 ...baseConfig,
11};
12
13// Nx plugins for rspack to build config object from Nx options and context.
14/**
15 * DTS Plugin is disabled in Nx Workspaces as Nx already provides Typing support for Module Federation
16 * The DTS Plugin can be enabled by setting dts: true
17 * Learn more about the DTS Plugin here: https://module-federation.io/configure/dts.html
18 */
19export default composePlugins(
20 withNx(),
21 withReact(),
22 withModuleFederation(config, { dts: false })
23);
24
If you have experience with our webpack
Module Federation support, you'll note that this file is very similar to the webpack.config.ts
files we would have generated. The only real difference is that the imports point to @nx/rspack
.
Module Federation is still under active development, however, all new development is being included in Rspack as well as the @module-federation/enhanced
package.
Module Federation 2.0 brings new features such as Federation Runtime and Runtime Plugins. These are significant advancements which offer a vast range of capabilities to Module Federation projects.
Nx itself has employed this strategy to solve a long-standing issue with shared workspace libraries wherein there was the possibility that a shared library would be served from a static remote. This in turn would prevent HMR updates to the library from being reflected in the locally served application. You can learn more about the NxRuntimeLibraryControlPlugin
here.
Step 4: Building and Serving
To build all the applications in the workspace, run the following:
~/myorg❯
npx nx run-many -t build
1
2 ✔ nx run remote1:build:production (2s)
3 ✔ nx run shell:build:production (526ms)
4
5———————————————————————————————————————————————————————————————————————————————————————
6
7 NX Successfully ran target build for 2 projects (3s)
8
This will build the applications with Rspack. You can observe the build artifacts in the dist/
folder.
To serve the Module Federation setup, we recommend only serving the host
application.
Nx purpose-built a serve
executor for Module Federation Projects. This executor will find all the remote
applications that the host
depends on and serves them, either statically or with HMR/Live Reloading.
Serving statically means that we can reuse the build artifacts for the remotes
for a faster dev-server startup time that is scalable. Combined with Nx caching, this works well to ensure a great developer experience.
You can learn more about how this works in our Nx Module Federation Technical Overview document.
Run the following command to serve the host
application with the remote
served statically:
~/myorg❯
npx nx serve shell
1> nx run shell:serve
2
3
4 NX Starting module federation dev-server for shell with 1 remotes
5
6
7 NX Building 1 static remotes...
8
9
10 NX Built 1 static remotes
11
12
13 NX Starting static remotes proxies...
14
15
16 NX Static remotes proxies started successfully
17
18[ Module Federation Manifest Plugin ]: Manifest will use absolute path resolution via its host at runtime, reason: publicPath='auto'
19<i> [webpack-dev-server] Project is running at:
20<i> [webpack-dev-server] Loopback: http://localhost:4200/, http://[::1]:4200/
21<i> [webpack-dev-server] 404s will fallback to '/index.html'
22● ━━━━━━━━━━━━━━━━━━━━━━━━━ (70%) sealing after module optimization [ Module Federation Manifest Plugin ] Manifest Link: {auto}/mf-manifest.json
23● ━━━━━━━━━━━━━━━━━━━━━━━━━ (98%) emitting emit Starting up http-server, serving dist
24
25http-server version: 14.1.1
26
27http-server settings:
28CORS: true
29Cache: -1 seconds
30Connection Timeout: 120 seconds
31Directory Listings: visible
32AutoIndex: visible
33Serve GZIP Files: false
34Serve Brotli Files: false
35Default File Extension: none
36
37Available on:
38 http://localhost:4202
39Hit CTRL-C to stop the server
40
41
42 NX Server ready at http://localhost:4200
43
If you navigate to http://localhost:4200
your application will render and you'll be able to navigate between the host
and the remote
.
Step 4: Deployment
Granted what we have currently is not something you'd likely see in a production application, we'll use it as is to demonstrate deployment with Zephyr Cloud.
Zephyr Cloud also has a recipe that you can follow to set up Nx React Module Federation with Zephyr Cloud here.
I'll break this section into sub-steps to make it easier to follow.
Step 1: Add package.json
and First Commit
First, we need to add package.json
files to our shell
and remote1
projects. This is used by Zephyr Cloud to determine the name and version of the projects for deployment.
Create the following files:
1{
2 "name": "shell",
3 "version": "0.0.0"
4}
5
Once this is done, add all staged files and create a git commit.
❯
git add .
❯
git commit -m "initial commit"
Step 2: Create a GitHub Repository
Next, we need to add a GitHub repository. It can be public or private, it will not affect the deployments by Zephyr Cloud.
Behind the scene, Zephyr Cloud will map your git configuration (remote origin url, organization or username, repository name and branch) to deploy your application. Without this step the deployment will fail.
If you don't already have the GitHub CLI installed, I would highly recommend it.
You can then run the following to create your GitHub Repository from your terminal:
~/myorg❯
gh repo create
1? What would you like to do? Push an existing local repository to GitHub
2? Path to local repository .
3? Repository name nx-zephyr-cloud-example
4? Repository owner Coly010
5? Description Example of Nx React Rspack Module Federation with Zephyr Cloud
6? Visibility Private
7✓ Created repository Coly010/nx-zephyr-cloud-example on GitHub
8 https://github.com/Coly010/nx-zephyr-cloud-example
9? Add a remote? Yes
10? What should the new remote be called? origin
11✓ Added remote https://github.com/Coly010/nx-zephyr-cloud-example.git
12? Would you like to push commits from the current branch to "origin"? Yes
13
Step 3: Add Zephyr Cloud
To add Zephyr Cloud itself, we need to install their zephyr-webpack-plugin
.
The plugin is indeed written for Webpack, however, one of the big advantages of Rspack is the interoperability it offers for the Webpack Ecosystem. You can learn more about this compatability here.
Run the following to install the plugin:
❯
npm install zephyr-webpack-plugin
Now that the plugin has been installed in our workspace, we need to update the rspack.config.ts
files to use it. This is a very simple two line change:
1import { withZephyr } from 'zephyr-webpack-plugin';
2
3export default composePlugins(
4 ...,
5 withZephyr()
6)
7
You'll need to make these updates to the following files:
shell/rspack.config.ts
shell/rspack.config.prod.ts
remote1/rspack.config.ts
For example, your shell/rspack.config.ts
file should now match the following:
1import { composePlugins, withNx, withReact } from '@nx/rspack';
2import {
3 withModuleFederation,
4 ModuleFederationConfig,
5} from '@nx/rspack/module-federation';
6import { withZephyr } from 'zephyr-webpack-plugin';
7
8import baseConfig from './module-federation.config';
9
10const config: ModuleFederationConfig = {
11 ...baseConfig,
12};
13
14// Nx plugins for rspack to build config object from Nx options and context.
15/**
16 * DTS Plugin is disabled in Nx Workspaces as Nx already provides Typing support for Module Federation
17 * The DTS Plugin can be enabled by setting dts: true
18 * Learn more about the DTS Plugin here: https://module-federation.io/configure/dts.html
19 */
20export default composePlugins(
21 withNx(),
22 withReact(),
23 withModuleFederation(config, { dts: false }),
24 withZephyr()
25);
26
Step 4: First Deployment
With all the rspack.config.ts
files updated, getting your first deployment is as simple as running:
~/myorg❯
npx nx run-many -t build --verbose
1> nx run remote1:build:production
2...
3
4 ZEPHYR Opening browser for authentication...
5 ZEPHYR Hi colum_nrwl_io!
6 ZEPHYR remote1.nx-zephyr-cloud-example.coly010#6
7 ZEPHYR
8 ZEPHYR Uploaded local snapshot in 152ms
9 ZEPHYR (12/12 assets uploaded in 235ms, 332.55kb)
10 ZEPHYR Deployed to Zephyr's edge in 352ms.
11 ZEPHYR
12 ZEPHYR https://colum_nrwl_io_6-remote1-nx-zephyr-cloud-example-c-e7ab3d770-ze.zephyrcloud.app
13
14...
15Rspack 1.0.4 compiled with 1 warning in 3.91 s
16
17> nx run shell:build:production
18...
19
20 ZEPHYR Hi colum_nrwl_io!
21 ZEPHYR shell.nx-zephyr-cloud-example.coly010#7
22 ZEPHYR
23 ZEPHYR Uploaded local snapshot in 165ms
24 ZEPHYR (10/10 assets uploaded in 202ms, 326.42kb)
25 ZEPHYR Deployed to Zephyr's edge in 248ms.
26 ZEPHYR
27 ZEPHYR https://colum_nrwl_io_7-shell-nx-zephyr-cloud-example-col-04ccb4027-ze.zephyrcloud.app
28
29...
30Rspack 1.0.4 compiled with 1 warning in 1.29 s
31
At this point, a page will likely be opened in your browser where you can create your Zephyr Cloud account and authenticate the CLI to allow it to deploy the applications to your account.
You'll note that the output from this is not the same as the output we received earlier when we ran npx nx run-many -t build
. In particular, the most recent set of logs contains the URLs of the deployed application (Note: your URL should be different):
~/myorg❯
npx nx run-many -t build --verbose
1> nx run remote1:build:production
2...
3 ZEPHYR https://colum_nrwl_io_6-remote1-nx-zephyr-cloud-example-c-e7ab3d770-ze.zephyrcloud.app
4
5
6> nx run shell:build:production
7...
8 ZEPHYR https://colum_nrwl_io_7-shell-nx-zephyr-cloud-example-col-04ccb4027-ze.zephyrcloud.app
9
Zephyr Cloud deployed our applications during the build process!
With Zephyr Cloud, it really is that easy to deploy your Module Federation Projects.
You can then visit the Zephyr Cloud Dashboard where you can get a more visual insight into your deployed projects.
Conclusion
Deploying Micro Frontend applications has always been a complex task, especially when it comes to managing multiple build artifacts and maintaining stability. However, with Nx's continued support for Module Federation and the integration of Zephyr Cloud, developers now have access to a streamlined, scalable solution that simplifies the deployment process significantly.
Zephyr Cloud's unique features, such as auto-deployment, live preview links, and seamless rollback capabilities, make it an invaluable tool for Micro Frontend orchestration. By following the steps outlined in this guide, you can effortlessly set up your Nx workspace, scaffold Module Federation projects, and leverage Zephyr Cloud for quick, hassle-free deployments.
For more information about Zephyr Cloud I highly recommend checking out their docs.