Microfrontend Configuration with Webpack
Overview
This document aims to explain the details related to Microfrontend’s configuration. It is required to utilize Webpack technology to expose Microfrontend’s content via a remote entry file, so the Shell and other Microfrontends (e.g. via Slot Components) are able to load and use it. Webpack is a powerful module bundler for JavaScript, which takes modules with dependencies and generates static assets representing those modules. Since Webpack version five, Module Federation technology, integrated with Webpack, is used to achieve these goals.
| For Angular based Microfrontends, consider using @angular-architects/module-federation package. This package is used internally by OneCX to load remote modules and is recommended for Angular based applications. |
Microfrontend Configuration with Webpack Explained
Each Microfrontend integrated with OneCX needs to have a configuration file for Webpack (usually called webpack.config.js), utilizing Module Federation to expose remote modules. For both module and Remote Components, a remote module needs to be exposed.
Important Elements of Webpack Configuration
Webpack configuration is going to contain important configuration describing the Microfrontend. This configuration is used by Webpack to create and expose a remote entry file containing the whole code required to load remote modules in other Applications using Module Federation.
Below, a Webpack configuration example of an Angular based Microfrontend is presented.
const { ModifyEntryPlugin } = require('@angular-architects/module-federation/src/utils/modify-entry-plugin')
const { share, withModuleFederationPlugin } = require('@angular-architects/module-federation/webpack')
const config = withModuleFederationPlugin({
name: 'example-ui',
filename: 'remoteEntry.js',
exposes: {
'./ExampleModule': './src/main.ts',
'./ExampleComponent': './src/remotes/example/example.component.main.ts'
},
shared: share({
'@angular/core': { requiredVersion: 'auto', includeSecondaries: true },
'@angular/forms': { requiredVersion: 'auto', includeSecondaries: true },
'@angular/common': { requiredVersion: 'auto', includeSecondaries: { skip: ['@angular/common/http/testing'] } },
'@angular/common/http': { requiredVersion: 'auto', includeSecondaries: true },
'@angular/platform-browser': { requiredVersion: 'auto', includeSecondaries: true },
'@angular/router': { requiredVersion: 'auto', includeSecondaries: true },
'@ngx-translate/core': { requiredVersion: 'auto' },
primeng: { requiredVersion: 'auto', includeSecondaries: true },
rxjs: { requiredVersion: 'auto', includeSecondaries: true },
'@onecx/accelerator': { requiredVersion: 'auto', includeSecondaries: true },
'@onecx/angular-accelerator': { requiredVersion: 'auto', includeSecondaries: true },
'@onecx/angular-auth': { requiredVersion: 'auto', includeSecondaries: true },
'@onecx/angular-integration-interface': { requiredVersion: 'auto', includeSecondaries: true },
'@onecx/angular-remote-components': { requiredVersion: 'auto', includeSecondaries: true },
'@onecx/angular-testing': { requiredVersion: 'auto', includeSecondaries: true },
'@onecx/angular-webcomponents': { requiredVersion: 'auto', includeSecondaries: true },
'@onecx/integration-interface': { requiredVersion: 'auto', includeSecondaries: true },
'@onecx/keycloak-auth': { requiredVersion: 'auto', includeSecondaries: true },
'@onecx/ngrx-accelerator': { requiredVersion: 'auto', includeSecondaries: true },
'@onecx/portal-integration-angular': { requiredVersion: 'auto', includeSecondaries: true },
'@onecx/portal-layout-styles': { requiredVersion: 'auto', includeSecondaries: true }
}),
sharedMappings: []
})
module.exports = config
const plugins = config.plugins.filter((plugin) => !(plugin instanceof ModifyEntryPlugin))
module.exports = {
...config,
plugins,
output: { uniqueName: 'example-ui', publicPath: 'auto' },
experiments: { ...config.experiments, topLevelAwait: true },
optimization: { runtimeChunk: false, splitChunks: false }
}
The most important elements of Webpack configurations are:
- Exposed content
-
Each Microfrontend can expose multiple modules and Remote Components. Every separate module and Remote Component needs to be defined as a separate, unique entry representing a remote module. Each entry is a Key-Value Pair:
- Key
-
Name of the exposed module.
- Value
-
File to be used for module bootstrap.
In the Angular example, there are two remote modules defined:
-
ExampleModule - Microfrontend’s remote module pointing to Microfrontend’s main.ts file.
-
ExampleComponent - Remote Component’s remote module pointing to component’s main.ts file.
| Module Federation considers any exposed content as a remote module. In the OneCX context, Microfrontends expose two types of content, being modules and Remote Components. |
- Shared resources
-
Each Microfrontend can define packages that can be shared with others. Every Microfrontend can specify what packages and with what versions are allowed to be shared. In the OneCX context, it is important to ensure the correct package sharing configuration dependent on the used packages used functionalities within the Microfrontend’s exposed content.
In the Angular example, there are multiple packages shared. All of them are related to OneCX. For the detailed explanation on package sharing with OneCX, please refer here. For even more information on how package sharing works, please refer here.
- Remote name
-
The unique name of the Microfrontend.
- Remote entry file name
-
The name of the remote entry file (usually
remoteEntry.js).
Related Resources
-
Content bootstrapping - based on the content type and expose method bootstrap mechanism needs to be adjusted.
-
Package sharing - based on the content of the Microfrontend different packages are required or should be considered for sharing.