<!-- Please make sure you have read the submission guidelines before posting an PR --> <!-- https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr --> <!-- Please make sure that your commit message follows our format --> <!-- Example: `fix(nx): must begin with lowercase` --> <!-- If this is a particularly complex change or feature addition, you can request a dedicated Nx release for this pull request branch. Mention someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they will confirm if the PR warrants its own release for testing purposes, and generate it for you if appropriate. --> ## Current Behavior <!-- This is the behavior we have today --> ## Expected Behavior <!-- This is the behavior we should expect with the changes in this PR --> ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes # --------- Co-authored-by: Colum Ferry <cferry09@gmail.com> Co-authored-by: Nicholas Cunningham <ndcunningham@gmail.com>
4.6 KiB
Federate a Module
Module Federation is a concept that allows developers to share code between applications at run-time. It is a way of doing micro-frontends, but it can also be used to share code between applications that are not micro-frontends.
In the context of Module Federation, a module can be thought as any piece of code, functionally independent, that can be reused in different applications. It can be a component, a service, a library, a utility, etc.
In order to share a module, it must be federated. This means that the module must be configured to be shared, and the application that wants to use it must be configured to use it.
Nx includes first class support for Module Federation for React and Angular applications. This means that you can federate modules in your workspace with a few simple commands.
{% callout type="info" title="Assumption" %} With this recipe we assume that you have already created a workspace with at least one React or Angular Module Federation host application. If you haven't, you can follow the Create a Host Recipe. {% /callout %}
Step 1: Create the module
We will create a module that exports a hello function. Since we are using Nx, we will create a library for this module.
Create a library
nx generate @nx/js:library hello --unitTestRunner=jest --projectNameAndRootFormat=as-provided
Update the hello.ts file with the following code:
export default function hello(): string {
return 'Hello from Nx';
}
Update hello/ barrel file index.ts with the following code:
export { default } from './lib/hello';
Step 2: Federate the module
Now that we have created the module, we need to configure it to be federated.
{% tabs %} {%tab label="React"%}
nx generate @nx/react:federate-module hello/src/index.ts --name=hello --remote=greeting
{% /tab %} {%tab label="Angular"%}
nx generate @nx/angular:federate-module hello/src/index.ts --name=hello --remote=greeting
{% /tab %} {% /tabs %}
{% callout type="note" title="Remote does not exist" %} If the remote provided does not exist (in this instance greeting), Nx will create it for you. {% /callout %}
This command will:
- Adds a module entry to the
greetingremote module federation config file.
{% tabs %} {%tab label="Typescript Config File"%}
import { ModuleFederationConfig } from '@nx/webpack';
const config: ModuleFederationConfig = {
name: 'greeting',
exposes: {
'./Module': './src/remote-entry.ts',
'./Hello': 'hello/src/index.ts', // <-- this line was added,
},
};
export default config;
{% /tab %} {%tab label="Javascript Config File"%}
module.exports = {
name: 'greeting',
exposes: {
'./Module': './src/remote-entry.ts',
'./Hello': 'hello/src/index.ts', // <-- this line was added
},
};
{% /tab %} {% /tabs %}
- Adds a Typescript path mapping to the
greeting/Hellomodule in your root TSConfig file.
{
"paths": {
"greeting/Module": ["greeting/src/remote-entry.ts"],
"greeting/Hello": ["hello/src/index.ts"] // <-- this line was added
}
}
Step 3: Use the module
Update the host application to use the federated module.
{% tabs %} {%tab label="Typescript Config File"%}
import { ModuleFederationConfig } from '@nx/webpack';
const config: ModuleFederationConfig = {
name: 'host',
remotes: ['greeting'], // <-- Ensure that greeting remote is listed here
};
export default config;
{% /tab %} {%tab label="Javascript Config File"%}
module.exports = {
name: 'host',
remotes: ['greeting'], // <-- Ensure that greeting remote is listed here
};
{% /tab %} {% /tabs %}
import hello from 'greeting/Hello';
export function App() {
return <div>{hello()}</div>;
}
export default App;
If you are using Angular, you would update the application in a similar fashion to use the federated module.
Step 4: Run the application
Just run the application as usual.
nx serve host
To start the application, use the following address: http://localhost:4200. Once opened, you'll see the message "Hello from Nx". This message is loaded from the greeting remote, which runs on port 4201.