To use Module Federation in Modern.js, we recommend using the official plugin @module-federation/modern-js
.
This section will introduce how to set up both producer and consumer applications using the official plugin. First, create two applications by following the Modern.js Quick Start.
After creating the applications, install the plugin for both projects:
After installing the plugin, you need to register it in the modern.config.js
file:
Next, modify the producer's code to export the Module Federation module.
Create the src/components/Button.tsx
file and export a Button component:
Then, add the module-federation.config.ts
file at the project root to configure the Module Federation module's name, shared dependencies, and exports:
Additionally, modify modern.config.ts
to provide a development environment port for the producer, allowing the consumer to access the producer's resources through this port:
Now, modify the consumer's code to use the module exported by the producer.
Add the module-federation.config.ts
file at the project root to configure the Module Federation module's name, shared dependencies, and the remote module to use:
mf-manifest.json
is the file produced by the producer after packaging, containing all the information about the modules exported by the producer.
Create a new route file src/routes/remote/page.tsx
and import the producer module:
At this point, importing remote/Button
will result in a type error because the local environment doesn't have the type for the remote module. Module Federation 2.0 provides type hints, which will automatically generate type definitions for remote modules during the producer's build and download them during the consumer's build.
To ensure the types take effect, add a new path
in tsconfig.json
:
In the consumer, we reference the remote module using remote/Button
. Here's a brief explanation of what this path specifically represents. You can abstract it as [remoteAlias]/[remoteExpose]
.
The first part, remoteAlias
, is the alias of the producer in the consumer. It is the key
configured in the remotes
field of the consumer's module-federation.config.ts
:
Here, we also abstract the remote address as [remoteModuleName]@[URL_ADDRESS]
. The part before @
must correspond to the module name of the producer.
The second part, remoteExpose
, is the key
configured in the exposes
field of the producer's module-federation.config.ts
.
Now, both the producer and consumer applications are set up. You can run modern dev
locally to start both applications.
Once started, the imports of the producer's modules in the consumer will no longer throw errors, and the types will be downloaded to the consumer application.
After modifying the producer's code, the consumer will automatically fetch the producer's types.
Access http://localhost:8080/remote
, and you will see that the page includes the Button
component from the producer's remote module.
You can refer to this example: Modern.js & Module Federation Basic Example.