- Description
- How to run
- MFE1 app
- Shell app
- Webpack Module Federation
- Web components and Angular styling
- Learn more
This example shows how to setup Webpack Module Federation where the shell uses a generic Angular component that acts as a wrapper for the remotely loaded Web component. The wrapper Angular component is provided by the @angular-architects/module-federation-tools npm package and can be used directly on the HTML or via Angular routing. This code demo also shows how to set the properties and consume the events from the Web component.
The remote webpack module executes a function that converts an Angular standalone component to a Web component.
The shell app is rendered in a red colored background and the remotely loaded mfe1 app is rendered in a blue colored background.
Note
Although the mfe1 app is using an Angular standalone component, the module federation setup shown in this example could also be used with a non-standalone Angular component. You do NOT have to use Angular standalone components to export Angular components as Web components.
- Go to
/code-demos/web-component-angular-architects-wrapper-ng16/shell-ng16
folder and runnpm i
, followed bynpm start
. This will start the shell app on http://localhost:4200. - Go to
/code-demos/web-component-angular-architects-wrapper-ng16/mfe1-ng16
folder and runnpm i
, followed bynpm start
. This will start the mfe1 app on http://localhost:4201.
The shell will load the Web component from the mfe1 in two ways:
- using the wrapper Angular component directly on HTML: the web component will load on the shell's page load.
- using the wrapper Angular component with Angular routing: the web component will load when navigating to
/mfe1
.
The mfe1 app is an Angular 16 app that contains an Angular standalone component named MyStandaloneComponent, which represents the micro frontend that we want to expose via Webpack Module Federation.
The AppRoutingModule Angular module contains a route that loads the MyStandaloneComponent
on /my-standalone-component
. You can use the Go to /my-standalone-component
link on the mfe1 app to load the MyStandaloneComponent
Angular component.
The mfe1 app will set the input of the MyStandaloneComponent
to test input value from dev platform
and subscribe to the output of the component which logs to the console when the Send message
button is clicked.
On the webpack configuration file for mfe1 app you will find the declaration of the webpack modules to expose:
exposes: {
"./standalone-component-as-web-component": "./src/app/my-standalone-component/remote-bootstrap.ts",
},
The above defines a webpack module that is named standalone-component-as-web-component
and that is mapped to the ./src/app/my-standalone-component/remote-bootstrap.ts file, which executes the bootstrapMyComponentAsync
function that converts the MyStandaloneComponent
Angular standalone component to a Web component.
Note
The Angular component is converted to a Web component using the createCustomElement
function from @angular/elements
. For more info see Angular elements overview.
Note
In the tsconfig.app.json config file we added the src/app/my-standalone-component/remote-bootstrap.ts
entry to the files
array to avoid a Typescript compilation error saying <filename> is missing from the TypeScript compilation. Please make sure it is in your tsconfig via the 'files' or 'include' property
.
When you run the mfe1 app you will see the text MFE1 dev platform
. This is to call out the fact that the mfe1 app is not exposed in its entirety via Webpack Module Federation, only the remote-bootstrap.ts file that executes the bootstrapMyComponentAsync function is. Everything else in the mfe1 app is there only with the sole purpose of supporting the local development of the mfe1 app, more specifically, the development of the MyStandaloneComponent
Angular component.
This means that the input value test input value from dev platform
set by the dev platform is not part of the exported component, neither is the subscription of the component's output that logs to the console when the Send message
is clicked.
The shell app is an Angular 16 app that loads a Web component exposed by the mfe1 app by using a generic Angular component that acts as a wrapper. The wrapper component is named WebComponentWrapper and is provided by the @angular-architects/module-federation-tools npm package.
The shell uses the WebComponentWrapper
in two ways:
directly on HTML
: the web component is loaded on the shell's page load. This way also allows easily setting the inputs and outputs.with Angular routing
: the web component will load when navigating to/mfe1
. You can also set inputs and outputs using theWebComponentWrapper
in this way but it's more limited, not so straightforward.
The WebComponentWrapper Angular component uses the loadRemoteModule
function to load the webpack module from the mfe1 app. Upon loading the webpack module, the bootstrapMyComponentAsync
is executed and registers a custom element in the CustomElementRegistry
with the name my-mfe-element
, which means that wherever the custom element <my-mfe-element></my-mfe-element>
is defined it will render the Web component from the mfe1 app.
Then, the WebComponentWrapper
creates a custom element in the DOM with the name from WebComponentWrapperOptions.elementName
, which in this example is set to my-mfe-element
. Once this is done the Web component gets rendered in this custom element.
The setup of Webpack Module Federation was done using the @angular-architects/module-federation npm package, which aims to streamline the setup of Webpack Module Federation for Angular apps. For more info see Basics of @angular-architects/module-federation npm package.
Also, read the official docs at:
- the readme page for the @angular-architects/module-federation npm package
- the tutorial for the @angular-architects/module-federation plugin
Beware of issues with styling when using web components. If styles from your Angular component that you have exposed as a Web component using @angular/elements
are bleeding out, then you might need to set your ViewEncapsulation to ViewEncapsulation.ShadowDom
, which uses the ShadowDOM specification, on the Angular component which is being passed to createCustomElement
.
In this example app, the ViewEncapsulation
configuration would be applied to the MyStandaloneComponent component.
For more info see: