-
Notifications
You must be signed in to change notification settings - Fork 10
docs: module federation webcomponents #53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| [#microfrontend-content-loading] | ||
| = Microfrontend Content Loading Mechanism | ||
|
|
||
| == Overview | ||
|
|
||
| This document explains how Microfrontend content is loaded in the OneCX platform using Module Federation. | ||
|
|
||
| It helps you: | ||
|
|
||
| - Understand available loading approaches | ||
| - Choose the correct integration approach | ||
| - Configure microfrontends correctly | ||
|
|
||
| Microfrontend integration is primarily determined by two factors: | ||
|
|
||
| * xref:./content-type.adoc[**Content Type**] | ||
| ** Module | ||
| ** Remote Component | ||
|
|
||
| * xref:./expose-method.adoc[**Expose Method**] | ||
| ** Angular | ||
| ** Web Component | ||
|
|
||
| These factors depend on the type of content exposed by the microfrontend and must be configured correctly in the Application Store. | ||
|
|
||
| IMPORTANT: *It is NOT recommended to use the Angular expose method.* Using the Angular expose method creates tight coupling between microfrontends and restricts the platform’s ability to support multiple frameworks and versions. | ||
|
|
||
| NOTE: OneCX uses https://webpack.js.org/concepts/module-federation/[Module Federation] with Webpack to load and expose microfrontends. | ||
|
|
||
| .Navigation | ||
| [cols="1,1"] | ||
| |=== | ||
| | xref:../index.adoc[← Previous: Introduction to Module Federation] | ||
| | xref:./content-type.adoc[Next: Content Type →] | ||
| |=== |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| [#content-type] | ||
| = Content Type in Microfrontend Loading | ||
|
|
||
| == Overview | ||
|
|
||
| Content Type defines what kind of UI is dynamically loaded as a microfrontend in the OneCX platform. | ||
|
|
||
| It determines whether you are loading a full feature (Module) or a reusable UI component (Remote Component). | ||
|
|
||
| Selecting the correct content type is important, as it affects how the microfrontend is loaded and displayed. | ||
|
|
||
| == Content Type Selection | ||
|
|
||
| .Content Type Selection | ||
| [.stripes-even,cols="33,33,~"] | ||
| |=== | ||
| | Use Case | Content Type | Loading Mechanism | ||
|
|
||
| | Full page or feature with routing | ||
| | Module | ||
| | xref:./shell-router.adoc[Shell UI Router] | ||
|
|
||
| | Reusable UI component embedded in a page | ||
| | Remote Component | ||
| | xref:./slot-component.adoc[Slot Component] | ||
| |=== | ||
|
|
||
| .Navigation | ||
| [cols="1,1"] | ||
| |=== | ||
| | xref:./content-loading.adoc[← Previous: Microfrontend Content Loading] | ||
| | xref:./shell-router.adoc[Next: Shell UI Router →] | ||
| |=== |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| [#expose-method] | ||
| = Expose Method in Microfrontend Loading | ||
|
|
||
| == Overview | ||
|
|
||
| The expose method is a factor considered by the respective loading mechanism (Shell UI Router or Slot Component) to ensure correct content loading. | ||
|
|
||
| == Usage in loading mechanisms | ||
| [cols="1,2", options="header"] | ||
| |=== | ||
| | Loading type | Impact | ||
| | Module loading | The `loadChildren` method and router configuration are affected. | ||
| | Remote component loading | A different mechanism for dynamic content creation is chosen. | ||
| |=== | ||
|
|
||
| More details about the impact of the expose method can be found xref:./webcomponents/index.adoc[here]. | ||
|
|
||
| .Navigation | ||
| [cols="1"] | ||
| |=== | ||
| | xref:../index.adoc[← Previous: Introduction to Module Federation] | ||
| |=== |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| [#module-federation-loading] | ||
| = Module Federation Loading Explained | ||
|
|
||
| Independent of the content type and expose method, the OneCX platform loads exposed content using **Module Federation**. | ||
|
|
||
| During this process, the exposed content is loaded using the file specified in the webpack configuration for the respective content. | ||
| As this example uses Webpack, this configuration is specified in the `webpack.config.js` file. | ||
|
|
||
| .Example | ||
| [source, javascript] | ||
| --- | ||
| const config = withModuleFederationPlugin({ | ||
| name: 'my-application-ui', | ||
| filename: 'remoteEntry.js', | ||
| exposes: { | ||
| './MyDefaultModule': './src/main.ts', | ||
| './MyRemoteComponent': './src/app/remotes/my-comp/my-comp.component.main.ts' | ||
| }, | ||
| ... | ||
| }) | ||
| --- | ||
| == Notes | ||
|
|
||
| * `MyDefaultModule` - The file is used for module loading. | ||
| * `MyRemoteComponent` - The file is used for remote component loading. | ||
|
|
||
| == Loading process | ||
|
|
||
| Files defined in the configuration are used to load the exposed content. These files should contain all the required setup to display content. | ||
|
|
||
| The implementation inside these files depends on the chosen expose method. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| [#shell-router] | ||
| = Shell UI Router | ||
|
|
||
| == Overview | ||
|
|
||
| The **Shell UI Router** acts as the central orchestrator, building the workspace and setting up routing based on backend configuration. It maps application paths to their respective microfrontend modules. At runtime, it uses **Module Federation** to dynamically load the required module when a route is activated. The loaded module is then rendered in the content area, enabling independent deployment and seamless navigation. | ||
|
|
||
| === Workspace and Route Configuration | ||
|
|
||
| The Shell UI Router builds the workspace using configuration data provided by backend services. This configuration contains all applications registered for a workspace along with their associated paths. | ||
|
|
||
| Each application must define a unique path. This path is used by the Shell UI Router to create routing rules and to identify which microfrontend module should be loaded for a given URL. | ||
|
|
||
| Based on this configuration, the Shell UI Router maps each path to its corresponding microfrontend module. These mappings form the foundation for routing and ensure that the correct module is loaded when a user navigates within the workspace. | ||
|
|
||
| === Router Initialization | ||
|
|
||
| Before handling any navigation, the Shell UI Router initializes the router using the workspace configuration. It reads the configured application paths and creates routing rules for each one. | ||
|
|
||
| These rules define how URLs are matched to microfrontend modules during runtime. For every application, a corresponding route is registered in the router. | ||
|
|
||
| This setup ensures that when a user navigates to a specific path, the Shell UI Router can correctly identify and trigger loading of the associated module. | ||
|
|
||
| === Route Structure and Properties | ||
|
|
||
| Each application is registered as a route in the Shell UI Router. Every route includes a defined path and a `loadChildren` method, along with additional properties used during routing. | ||
|
|
||
| The `path` determines how a URL is matched, while `loadChildren` defines how the corresponding microfrontend module is loaded when the route is activated. | ||
|
|
||
| These route definitions allow the Shell UI Router to connect navigation events with the correct module loading behavior, ensuring that the appropriate content is displayed. | ||
|
|
||
| === Module Loading using Module Federation | ||
|
|
||
| When a route is activated, the Shell UI uses the `loadChildren` method to load the corresponding microfrontend module. | ||
|
|
||
| The `loadChildren` method is responsible for loading the remote module into the Shell UI’s memory using `@angular-architects/module-federation`. This enables dynamic loading of independently deployed applications at runtime. | ||
|
|
||
| Once the remote module is successfully loaded, it is passed to the router, which renders the module’s content in the content area of the application. | ||
|
|
||
| === Runtime Navigation Flow (Example) | ||
|
|
||
| Consider a workspace that includes a User Profile application with the path `/user`. | ||
|
|
||
| When the application starts, the Shell UI registers a route for `/user` based on the workspace configuration. If the user navigates to a URL starting with `/user`, the router matches this route. | ||
|
|
||
| The `loadChildren` method is then triggered, and the Shell UI uses Module Federation to load the User Profile microfrontend module. | ||
|
|
||
| Once loaded, the router renders the module in the content area, allowing the user to interact with the application. | ||
|
|
||
| .Navigation | ||
| [cols="1,1"] | ||
| |=== | ||
| | xref:./content-type.adoc[← Previous: Content Type] | ||
| | xref:./slot-component.adoc[Next: Slot Component →] | ||
| |=== |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| [#slot-component] | ||
| = Slot Component | ||
|
|
||
| == Overview | ||
| The slot component mechanism in OneCX is used for dynamically rendering remote components in specific locations on a page using **Module Federation**. Slots are configurable at runtime. | ||
|
|
||
| Remote component loading is handled by the slot component. The remote component loading mechanism can be found xref:../../architecture/remote-components.adoc[here]. | ||
|
|
||
| == Key aspects | ||
|
|
||
| * The loading process starts when a slot component is rendered on a page. | ||
| * Exposed remote component content is loaded using `@angular-architects/module-federation`. | ||
| * After successful loading, the component is rendered inside the slot component. | ||
| * Rendering uses a dynamic content creation mechanism based on the chosen expose method. | ||
|
|
||
| == Slot rendering process | ||
| The following flow describes how slot rendering works: | ||
|
|
||
| * App1 owns the page and defines a **slot location**. | ||
| * App2 exposes a **remote component** using **module federation** that can be used in the slot. | ||
| * Both App1 and App2 are available in the **workspace**. | ||
| * The slot defined in App1 is **activated** in the **workspace**. | ||
| * A remote component from App2 is **assigned** to the slot in App1. | ||
| * When the slot is displayed, App1 dynamically loads the component **exposed** by App2 using **module federation**. | ||
| * The component is then **rendered** in the slot using the technology defined in the **remote component configuration**. | ||
|
|
||
| .Navigation | ||
| [cols="1,1"] | ||
| |=== | ||
| | xref:./shell-router.adoc[← Previous: Shell UI Router] | ||
| | xref:./expose-method.adoc[Next: Expose Method →] | ||
| |=== |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| [#onecx-adaptation-to-webcomponent-method] | ||
| = OneCX Adaptation to Webcomponent Method | ||
|
|
||
| As stated in xref:./microfrontend-content-loading.adoc[Microfrontend content loading documentation], every method of Microfrontend's content exposal has an impact on the OneCX platform behavior for both module and Remote Component loading. The adaptations made by OneCX to work with Web Components were briefly mentioned in the Web Components preview, however depending on the content type, the behavior varies. | ||
|
|
||
| // TODO: Link to guide of Webcomponent expose method | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why TODO comment?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. from legacy docs. addressed in this PR - #55 |
||
| [#module-loading-behavior] | ||
| == Module Loading Behavior | ||
|
|
||
| === Overview | ||
|
|
||
| This section explains how the Shell UI loads and renders Microfrontend modules using the Webcomponent expose method. It describes how routing, module federation, and Web Components work together, where the Shell loads the module and Web Components handle rendering through custom elements. | ||
|
|
||
| // TODO: Link to guide of Webcomponent expose method | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why TODO comment?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. from legacy docs. addressed in this PR - #55 |
||
|
|
||
| * *Shell UI Responsibility* - The Shell UI App is responsible for displaying Microfrontend's module when router navigation is matched for a desired Microfrontend. | ||
|
|
||
| * *Webcomponent Adaptation in loadChildren* - With Webcomponent method, Shell UI will adapt the loadChildren method to: | ||
|
|
||
| . load desired remote module using https://www.npmjs.com/package/@angular-architects/module-federation[@angular-architects/module-federation] (no change). | ||
| . use **WebComponentLoaderModule** as the module to be lazy-loaded (instead of the Microfrontend's module). | ||
|
|
||
| * *loadChildren Behavior* - The https://angular.dev/guide/ngmodules/lazy-loading[loadChildren method bound to a Route] is an asynchronous method that in the end should return a module to be displayed when activating a certain Route. | ||
|
|
||
| * *Module Loading with Webcomponent* - With Webcomponent method, the desired Microfrontend's module is still being loaded using https://www.npmjs.com/package/@angular-architects/module-federation[@angular-architects/module-federation]. | ||
|
|
||
| * *Custom Elements Registration* - During that loading, it should register a component in the Custom Elements Registry, as mentioned in the previous section. | ||
|
|
||
| * *Shell UI Rendering Responsibility* - For OneCX platform, it means that it no longer should load the Microfrontend's module directly but ensure that the HTML code has the correct Custom Element in order to display the module. | ||
|
|
||
| * *WebComponentLoaderModule* - **WebComponentLoaderModule** is a simple Angular module with a Router set up to always display **WebComponentLoaderComponent**. | ||
|
|
||
| * *WebComponentLoaderComponent Responsibility* - This component is responsible for rendering the HTML element required to display the module with Web Components Custom Elements. | ||
|
|
||
| * *Router Navigation Handling* - Whenever Shell UI's router detects a change of the Microfrontend (another path is matched than the current one), it calls **loadChildren method** to load the desired module and returns **WebComponentLoaderModule**. | ||
|
|
||
| * *Component Initialization* - The module then creates and initializes **WebComponentLoaderComponent**, which, after initializations, creates the HTML element. | ||
|
|
||
| * *Web Components Binding* - Then Web Components using Custom Elements technology bounds the Microfrontend's module to the created element. | ||
|
|
||
| // Add new guide from oneCx section here | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the purpose of this comment?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As document was divided new link has to be added in this doc. Linking is done |
||
| * *Reference* - For a detailed guide on how to expose Microfrontend's module via Webcomponent method, please refer here. | ||
|
|
||
| [#remote-component-behavior] | ||
| == Remote Component Behavior | ||
|
|
||
| === Overview | ||
|
|
||
| This section explains how the Slot Component renders Microfrontend Remote Components using the Webcomponent method. Instead of directly creating Angular components, the Slot Component creates an HTML host element, while the microfrontend registers and binds its component using Web Components and Custom Elements. | ||
|
|
||
| * *Slot Component Responsibility* | ||
| Slot Component is responsible for displaying Microfrontend's Remote Components during Slot Component initialization. | ||
|
|
||
| * *Webcomponent Adaptation in Slot Component* - With the Webcomponent method, the Slot Component will adapt the steps to: | ||
|
|
||
| . load desired remote content using https://www.npmjs.com/package/@angular-architects/module-federation[@angular-architects/module-federation] (no change). | ||
| . create HTML element directly inside a container (instead of creating Microfrontend's Remote Component instance). | ||
|
|
||
| * *Dynamic Content Creation* | ||
| The Slot Component content is based on https://angular.dev/api/core/ViewContainerRef[Angular ViewContainerRef] to dynamically create content inside the Slot Component. | ||
|
|
||
| * *Module Loading with Webcomponent* - With Webcomponent method, the desired Microfrontend's Remote Component is still being loaded using https://www.npmjs.com/package/@angular-architects/module-federation[@angular-architects/module-federation]. | ||
|
|
||
| * *Custom Elements Registration* - During that loading, it should register a component in the Custom Elements Registry, as mentioned in the previous section. | ||
|
|
||
| * *OneCX Rendering Responsibility* - For OneCX platform, it means that it no longer should create the Microfrontend's component directly but ensure that the HTML code has the correct element in order to display the component. | ||
|
|
||
| * *Webcomponent Method Difference* - The difference with the Webcomponent method is that, from the OneCX platform's perspective, no component needs to be created. Instead, a "host" element must be created to allow Web Components' Custom Elements to display desired content. | ||
|
|
||
| // Add new guide from oneCx section here | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the purpose of this comment?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As document was divided new link has to be added in this doc. Linking is done |
||
| * *Reference* - For a detailed guide on how to expose Microfrontend's Remote Components via Webcomponent method, please refer here. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| = Custom Elements in OneCX | ||
|
|
||
| == Overview | ||
| This article explains how Custom Elements are used in OneCX to dynamically render microfrontend content by binding UI components to HTML elements. It describes the role of the Shell UI, Application Store, and microfrontends in loading, registering, and displaying content using the Web Component approach. | ||
|
|
||
| == How It Works | ||
|
|
||
| * ** Custom Elements** - Custom Elements are part of the Web Components technology. It is a set of tools used to achieve the bounding between components and HTML elements. | ||
|
|
||
| * **Configuration** - OneCX platform will create HTML elements specified via configuration whenever a module or Remote Component has to be displayed on a page. | ||
|
|
||
| * **Content loading in OneCX** - There are 2 steps that OneCX platform takes when dealing with content loading with Webcomponent expose method: | ||
|
|
||
| ** Load exposed content via Module Federation into memory | ||
| ** Create an HTML element on a page to which exposed content should be bound | ||
|
|
||
| * **Responsibility of Microfrontend** - In the Microfrontend content loading, it was mentioned that when exposing Microfrontend content, files specified per content should take care of all setup needed to display it. | ||
|
|
||
| * **Custom Element Registration** - With Webcomponent method, those files need to contain source code, which will register the Custom Element in the Custom Elements Registry. | ||
|
|
||
| * **Binding Components to Elements** - a file used for content loading needs to use Web Components to assign some component to the HTML element that OneCX platform will render. | ||
|
|
||
| * **Rendering** - When OneCX platform creates this HTML element on a page, the Custom Elements Registry will use the assigned component and display it on a page. | ||
|
|
||
| .Navigation | ||
| [cols="1,1"] | ||
| |=== | ||
| | xref:./index.adoc[← Previous: Introduction to Web Components] | ||
| | xref:./expose-method-requirements.adoc[Next: Webcomponent Expose Method Requirements →] | ||
| |=== |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| [#expose-microfrontends-content-as-web-components] | ||
| == Expose Microfrontend's Content as Web Components | ||
| OneCX platform offers different ways of xref:../../../architecture/mfe.adoc[exposing Microfrontend's content]. One of them is **Webcomponent method**. | ||
|
|
||
| When exposing content with Webcomponent method, it is required to ensure the correct setup. For exposing Angular content, there are functionalities provided via the <<onecx/angular-webcomponents, @onecx/angular-webcomponents>> library. For a detailed guide on how to expose Microfrontend's content via Webcomponent method, please refer here. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is the last sentence intended? If yes can we make the reference clearer?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes linked relevant document |
||
|
|
||
| [[angular_issues]] | ||
| [IMPORTANT] | ||
| ==== | ||
| Using **<<onecx/angular-webcomponents, @onecx/angular-webcomponents>>** library, according to the guide, is the recommended way of exposing Angular content. The set of functionalities provided via the library is taking care of all requirements related to the Web Components adaptation. Apart from automatic registration to the Custom Elements Registry, they ensure that the following issues are covered: | ||
|
|
||
| * Every module and Remote Component is going to have its own router. Routers (Shell's router, displayed module's router, and router of each displayed Remote Component) need to be synchronized so each can react to the router events. | ||
| * A Single Angular version can only create one platform to operate on, which means that for every content loaded within a page, the same platform has to be used for a specific version. | ||
| * ngZone of Shell UI has to be shared with all modules and Remote Components to allow Web Components to function correctly. | ||
|
|
||
| In-depth explanations for those issues can be found in the https://www.angulararchitects.io/en/blog/multi-framework-and-version-micro-frontends-with-module-federation-the-good-the-bad-the-ugly/[Module Federation multi-framework and version micro frontends document]. | ||
|
|
||
| ==== | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Headings looking odd/inconsistent |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| === Webcomponent Expose Method Requirements | ||
|
|
||
| To correctly use Webcomponent expose method, 2 requirements need to be fullfield: | ||
|
|
||
| . Database is correctly configured for module or Remote Component | ||
| .. **technology** set to **WebComponent** | ||
| .. **tag name** set to agreed **HTML element name** | ||
| . Microfrontend is adapted to expose Web Components compliant content | ||
| .. desired component needs to be registered as Custom Element in the Custom Elements Registry | ||
| .. Angular issues are covered (use the `<<onecx/angular-webcomponents, @onecx/angular-webcomponents>>` library to cover them by default) | ||
| ... multiple routers synchronization | ||
| ... ngZone sharing | ||
| ... platform sharing | ||
|
|
||
| NOTE: Database configuration is easy to set up using the Application Store Application. | ||
|
|
||
| IMPORTANT: To ensure Microfrontend compliance with Web Components for Angular modules and Remote Components, it is recommended to use the **<<onecx/angular-webcomponents, @onecx/angular-webcomponents>>** library. | ||
|
|
||
| .Navigation | ||
| [cols="1"] | ||
| |=== | ||
| | xref:./custom-elements.adoc[← Previous: Custom Elements] | ||
| |=== |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this xref working? (cannot see the adoc in this folder)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no. addressed in main PR #55