{"id":6180,"date":"2022-05-07T20:08:00","date_gmt":"2022-05-07T18:08:00","guid":{"rendered":"https:\/\/www.angulararchitects.io\/?p=6180"},"modified":"2024-01-19T15:37:29","modified_gmt":"2024-01-19T14:37:29","slug":"module-federation-with-angulars-standalone-components","status":"publish","type":"post","link":"https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/","title":{"rendered":"Module Federation with Angular&#8217;s Standalone Components"},"content":{"rendered":"<div class=\"wp-post-series-box series-module-federation wp-post-series-box--expandable\">\n\t\t\t<input id=\"collapsible-series-module-federation69d1265d891f5\" class=\"wp-post-series-box__toggle_checkbox\" type=\"checkbox\">\n\t\n\t<label\n\t\tclass=\"wp-post-series-box__label\"\n\t\t\t\t\tfor=\"collapsible-series-module-federation69d1265d891f5\"\n\t\t\ttabindex=\"0\"\n\t\t\t\t>\n\t\t<p class=\"wp-post-series-box__name wp-post-series-name\">\n\t\t\tThis is post 9 of 10 in the series <em>&ldquo;Module Federation&rdquo;<\/em>\t\t<\/p>\n\t\t\t<\/label>\n\n\t\t\t<div class=\"wp-post-series-box__posts\">\n\t\t\t<ol>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/the-microfrontend-revolution-module-federation-in-webpack-5\/\">The Microfrontend Revolution: Module Federation in Webpack 5<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/the-microfrontend-revolution-part-2-module-federation-with-angular\/\">The Microfrontend Revolution: Module Federation with Angular<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/dynamic-module-federation-with-angular\/\">Dynamic Module Federation with Angular<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/dynamic-module-federation-with-angular-2\/\">Building A Plugin-based Workflow Designer With Angular and Module Federation<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/getting-out-of-version-mismatch-hell-with-module-federation\/\">Getting Out of Version-Mismatch-Hell with Module Federation<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/using-module-federation-with-monorepos-and-angular\/\">Using Module Federation with (Nx) Monorepos and Angular<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/pitfalls-with-module-federation-and-angular\/\">Pitfalls with Module Federation and Angular<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/multi-framework-and-version-micro-frontends-with-module-federation-your-4-steps-guide\/\">Multi-Framework and -Version Micro Frontends with Module Federation: Your 4 Steps Guide<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><span class=\"wp-post-series-box__current\">Module Federation with Angular&#8217;s Standalone Components<\/span><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/whats-new-in-angular-architects-module-federation-14-3\/\">What&#8217;s New in our Module Federation Plugin 14.3?<\/a><\/li>\n\t\t\t\t\t\t\t<\/ol>\n\t\t<\/div>\n\t<\/div>\n<p>Most tutorials on Module Federation and Angular expose Micro Frontends in the form of NgModules. However, with the introduction of Standalone Components we will have lightweight Angular solutions not leveraging NgModules anymore. This leads to the question: How to use Module Federation in a world without NgModules?<\/p>\n<\/p>\n<p>In this article, I give answers. We see both, how to expose a bunch of routes pointing to Standalone Components and how to load an individual Standalone Component. For this, I've updated my example to fully work without NgModules:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2022\/05\/result.png\" alt=\"The example was updated to fully use Standalone Components\" \/><\/p>\n<p>Please find the \ud83d\udcc2 <a href=\"https:\/\/github.com\/manfredsteyer\/module-federation-plugin-example\/tree\/standalone-solution\">source code here<\/a> (branch: standalone-solution).<\/p>\n<h2>Router Configs vs. Standalone Components<\/h2>\n<p>In general, we could directly load Standalone Components via Module Federation. While such a fine-grained integration seems to be fine for plugin-systems, Micro Frontends are normally more coarse-grained. It's usual that they represent a whole business domain which in general contains several use cases belonging together.<\/p>\n<p>Interestingly, Standalone Components belonging together can be grouped using a router config. Hence, we can expose and lazy load such router configurations.<\/p>\n<h2>Initial Situation: Our Micro Frontend<\/h2>\n<p>The Micro Frontend used here is a simple Angular application bootstrapping a Standalone Component:<\/p>\n<pre><code class=\"language-typescript\"> \/\/ projects\/mfe1\/src\/main.ts\n\n import { environment } from &#039;.\/environments\/environment&#039;;\n import { enableProdMode, importProvidersFrom } from &#039;@angular\/core&#039;;\n import { bootstrapApplication } from &#039;@angular\/platform-browser&#039;;\n import { AppComponent } from &#039;.\/app\/app.component&#039;;\n import { RouterModule } from &#039;@angular\/router&#039;;\n import { MFE1_ROUTES } from &#039;.\/app\/mfe1.routes&#039;;\n\n if (environment.production) {\n   enableProdMode();\n }\n\n bootstrapApplication(AppComponent, {\n   providers: [\n     importProvidersFrom(RouterModule.forRoot(MFE1_ROUTES))\n   ]\n });<\/code><\/pre>\n<p>When bootstrapping, the application registers its router config <code>MFE1_ROUTES<\/code> via services providers. This router config points to several Standalone Components:<\/p>\n<pre><code class=\"language-typescript\"> \/\/ projects\/mfe1\/src\/app\/mfe1.routes.ts\n\n import { Routes } from &#039;@angular\/router&#039;;\n import { FlightSearchComponent } from &#039;.\/booking\/flight-search\/flight-search.component&#039;;\n import { PassengerSearchComponent } from &#039;.\/booking\/passenger-search\/passenger-search.component&#039;;\n import { HomeComponent } from &#039;.\/home\/home.component&#039;;\n\n export const MFE1_ROUTES: Routes = [\n     {\n         path: &#039;&#039;,\n         component: HomeComponent,\n         pathMatch: &#039;full&#039;\n     },\n     {\n         path: &#039;flight-search&#039;,\n         component: FlightSearchComponent\n     },\n     {\n         path: &#039;passenger-search&#039;,\n         component: PassengerSearchComponent\n     }\n ];<\/code><\/pre>\n<p>Here, <code>importProvidersFrom<\/code> bridges the gap between the existing <code>RouterModule<\/code> and the world of Standalone Components. As a replacement for this, future versions of the router will expose a function for setting up the router's providers. According to the underlying CFP, this function will be called <code>configureRouter<\/code>.<\/p>\n<p>The shell used here is just an ordinary Angular application. Using lazy loading, we are going to make it reference the Micro Frontend at runtime.<\/p>\n<h2>Activating Module Federation<\/h2>\n<p>To get started, let's install the Module Federation plugin and activate Module Federation for the Micro Frontend:<\/p>\n<pre><code class=\"language-bash\">npm i @angular-architects\/module-federation\n\n ng g @angular-architects\/module-federation:init --project mfe1 --port 4201 --type remote<\/code><\/pre>\n<p>This command generates a <code>webpack.config.js<\/code>. For our purpose, we have to modify the <code>exposes<\/code> section as follows:<\/p>\n<pre><code class=\"language-javascript\"> const { shareAll, withModuleFederationPlugin } = require(&quot;@angular-architects\/module-federation\/webpack&quot;);\n\n module.exports = withModuleFederationPlugin({\n   name: &quot;mfe1&quot;,\n\n   exposes: {\n     \/\/ Preferred way: expose corse-grained routes\n     &quot;.\/routes&quot;: &quot;.\/projects\/mfe1\/src\/app\/mfe1.routes.ts&quot;,\n\n     \/\/ Technically possible, but not preferred for Micro Frontends:\n     \/\/ Exposing fine-grained components\n     &quot;.\/Component&quot;: &quot;.\/projects\/mfe1\/src\/app\/my-tickets\/my-tickets.component.ts&quot;,\n   },\n\n   shared: {\n     ...shareAll({ singleton: true, strictVersion: true, requiredVersion: &quot;auto&quot; }),\n   }\n\n });<\/code><\/pre>\n<p>This configuration exposes both, the Micro Frontend's router configuration (pointing to Standalone Components) and a Standalone Component.<\/p>\n<h2>Static Shell<\/h2>\n<p>Now, let's also activate Module Federation for the shell. In this section, I focus on Static Federation. This means, we are going to map the paths pointing to our Micro Frontends in the webpack.config.js. <\/p>\n<blockquote>\n<p>The next section shows how to switch to Dynamic Federation, where we can define the key data for loading a Micro Frontend at runtime.<\/p>\n<\/blockquote>\n<p>To enable Module Federation for the shell, let's execute this command:<\/p>\n<pre><code class=\"language-bash\">ng g @angular-architects\/module-federation:init --project shell --port 4200 --type host<\/code><\/pre>\n<p>The <code>webpack.config.js<\/code> generated for the shell needs to point to the Micro Frontend:<\/p>\n<pre><code class=\"language-javascript\"> const { shareAll, withModuleFederationPlugin } = require(&quot;@angular-architects\/module-federation\/webpack&quot;);\n\n module.exports = withModuleFederationPlugin({\n\n   remotes: {\n     &quot;mfe1&quot;: &quot;http:\/\/localhost:4201\/remoteEntry.js&quot;,\n   },\n\n   shared: {\n     ...shareAll({ singleton: true, strictVersion: true, requiredVersion: &quot;auto&quot; }),\n   }\n\n });<\/code><\/pre>\n<p>As we are going with static federation, we also need typings for all configured paths (EcmaScript modules) referencing Micro Frontends:<\/p>\n<pre><code class=\"language-typescript\"> \/\/ projects\/shell\/src\/decl.d.ts\n\n declare module &#039;mfe1\/*&#039;;<\/code><\/pre>\n<p>Now, all it takes is a lazy route in the shell, pointing to the routes and the Standalone Component exposed by the Micro Frontend:<\/p>\n<pre><code class=\"language-javascript\"> \/\/ projects\/shell\/src\/app\/app.routes.ts\n\n import { Routes } from &#039;@angular\/router&#039;;\n import { HomeComponent } from &#039;.\/home\/home.component&#039;;\n import { NotFoundComponent } from &#039;.\/not-found\/not-found.component&#039;;\n import { ProgrammaticLoadingComponent } from &#039;.\/programmatic-loading\/programmatic-loading.component&#039;;\n\n export const APP_ROUTES: Routes = [\n     {\n       path: &#039;&#039;,\n       component: HomeComponent,\n       pathMatch: &#039;full&#039;\n     },\n\n     {\n       path: &#039;booking&#039;,\n       loadChildren: () =&gt; import(&#039;mfe1\/routes&#039;).then(m =&gt; m.BOOKING_ROUTES)\n     },\n\n     {\n       path: &#039;my-tickets&#039;,\n       loadComponent: () =&gt; \n           import(&#039;mfe1\/Component&#039;).then(m =&gt; m.MyTicketsComponent)\n     },\n\n     [...]\n\n     {\n       path: &#039;**&#039;,\n       component: NotFoundComponent\n     }\n ];<\/code><\/pre>\n<h2>Alternative: Dynamic Shell<\/h2>\n<p>Now, let's move to dynamic federation. Dynamic Federation means, we don't want to define our remote upfront in the shell's <code>webpack.config.js<\/code>. Hence, let's comment out the remote section there:<\/p>\n<pre><code class=\"language-javascript\"> const { shareAll, withModuleFederationPlugin } = require(&quot;@angular-architects\/module-federation\/webpack&quot;);\n\n module.exports = withModuleFederationPlugin({\n\n   \/\/ remotes: {\n   \/\/   &quot;mfe1&quot;: &quot;http:\/\/localhost:4201\/remoteEntry.js&quot;,\n   \/\/ },\n\n   shared: {\n     ...shareAll({ singleton: true, strictVersion: true, requiredVersion: &quot;auto&quot; }),\n   }\n\n });<\/code><\/pre>\n<p>Also, in the shell's router config, we need to switch out the dynamic <code>imports<\/code> used before by calls to <code>loadRemoteModule<\/code>:<\/p>\n<pre><code class=\"language-typescript\"> \/\/ projects\/shell\/src\/app\/app.routes.ts\n\n import { Routes } from &#039;@angular\/router&#039;;\n import { HomeComponent } from &#039;.\/home\/home.component&#039;;\n import { NotFoundComponent } from &#039;.\/not-found\/not-found.component&#039;;\n import { ProgrammaticLoadingComponent } from &#039;.\/programmatic-loading\/programmatic-loading.component&#039;;\n import { loadRemoteModule } from &#039;@angular-architects\/module-federation&#039;;\n\n export const APP_ROUTES: Routes = [\n     {\n       path: &#039;&#039;,\n       component: HomeComponent,\n       pathMatch: &#039;full&#039;\n     },\n     {\n       path: &#039;booking&#039;,\n       loadChildren: () =&gt; \n         loadRemoteModule({\n           type: &#039;module&#039;,\n           remoteEntry: &#039;http:\/\/localhost:4201\/remoteEntry.js&#039;,\n           exposedModule: &#039;.\/routes&#039;\n         })\n         .then(m =&gt; m.MFE1_ROUTES)\n     },\n     {\n       path: &#039;my-tickets&#039;,\n       loadComponent: () =&gt; \n         loadRemoteModule({\n           type: &#039;module&#039;,\n           remoteEntry: &#039;http:\/\/localhost:4201\/remoteEntry.js&#039;,\n           exposedModule: &#039;.\/Component&#039;\n         })\n         .then(m =&gt; m.MyTicketsComponent)\n     },\n     [...]\n     {\n       path: &#039;**&#039;,\n       component: NotFoundComponent\n     }\n ];<\/code><\/pre>\n<p>The <code>loadRemoteModule<\/code> function takes all the key data, Module Federation needs for loading the remote. This key data is just several strings, hence you can load it from literally everywhere.<\/p>\n<h2>Bonus: Programmatic Loading<\/h2>\n<p>While most of the times, we will load Micro Frontends (remotes) via the router, we can also load exposed components programmatically. For this, we need a placeholder marked with a template variable for the component in question:<\/p>\n<pre><code class=\"language-html\"> &lt;h1&gt;Programmatic Loading&lt;\/h1&gt;\n\n &lt;div&gt;\n     &lt;button (click)=&quot;load()&quot;&gt;Load!&lt;\/button&gt;\n &lt;\/div&gt;\n\n &lt;div #placeHolder&gt;&lt;\/div&gt;<\/code><\/pre>\n<p>We get hold of this placeholder's <code>ViewContainer<\/code> via the <code>ViewChild<\/code> decorator:<\/p>\n<pre><code class=\"language-typescript\"> \/\/ projects\/shell\/src\/app\/programmatic-loading\/programmatic-loading.component.ts\n\n import { Component, OnInit, ViewChild, ViewContainerRef } from &#039;@angular\/core&#039;;\n\n @Component({\n   selector: &#039;app-programmatic-loading&#039;,\n   standalone: true,\n   templateUrl: &#039;.\/programmatic-loading.component.html&#039;,\n   styleUrls: [&#039;.\/programmatic-loading.component.css&#039;]\n })\n export class ProgrammaticLoadingComponent implements OnInit {\n\n   @ViewChild(&#039;placeHolder&#039;, { read: ViewContainerRef })\n   viewContainer!: ViewContainerRef;\n\n   constructor() { }\n\n   ngOnInit(): void {\n   }\n\n   async load(): Promise&lt;void&gt; {\n\n       const m = await import(&#039;mfe1\/Component&#039;);\n       const ref = this.viewContainer.createComponent(m.MyTicketsComponent);\n       \/\/ const compInstance = ref.instance;\n       \/\/ compInstance.ngOnInit()\n   }\n\n }<\/code><\/pre>\n<p>This example shows a solution for Static Federation. Hence a dynamic <code><code>import<\/code><\/code> is used for getting hold of the Micro Frontend.<\/p>\n<p>After importing the remote component, we can instantiate it using the <code>ViewContainer<\/code>'s <code>createComponent<\/code> method. The returned reference (ref) points to the component instance with it's <code>instance<\/code> property. The instance allows to interact with the component, e. g. to call methods, set property, or setup event handlers.<\/p>\n<p>If we wanted to switch to Dynamic Federation, we would again use <code><code>loadRemoteModule<\/code><code> instead of the dynamic <\/code><code>import<\/code><\/code>: <\/p>\n<pre><code class=\"language-typescript\"> async load(): Promise&lt;void&gt; {\n\n     const m = await loadRemoteModule({\n       type: &#039;module&#039;,\n       remoteEntry: &#039;http:\/\/localhost:4201\/remoteEntry.js&#039;,\n       exposedModule: &#039;.\/Component&#039;\n     });\n\n     const ref = this.viewContainer.createComponent(m.MyTicketsComponent);\n     \/\/ const compInstance = ref.instance;\n }<\/code><\/pre>\n<h2>What's next? More on Architecture!<\/h2>\n<p>So far, we've seen how to decompose a huge client into several Micro Frontends that can even use different frameworks. However, when dealing with enterprise-scale frontends, several additional questions come in mind:<\/p>\n<ul>\n<li>According to which criteria can we subdivide a huge application into sub-domains?<\/li>\n<li>How can we enforce loosely coupling?<\/li>\n<li>How can we make sure, the solution is maintainable for years or even decades?<\/li>\n<li>Which proven patterns should we use?<\/li>\n<li>Which other options from Micro Frontends are provided by Module Federation?<\/li>\n<li>Shall we go with a monorepo or with multiple ones?<\/li>\n<\/ul>\n<p>Our free eBook (about 120 pages) covers all these questions and more:<\/p>\n<p><a href=\"https:\/\/www.angulararchitects.io\/book\"><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2020\/12\/cover-small.png\" alt=\"free ebook\"><\/a><\/p>\n<p>Feel free to <a href=\"https:\/\/www.angulararchitects.io\/book\">download it here<\/a> now!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is post 9 of 10 in the series &ldquo;Module Federation&rdquo; The Microfrontend Revolution: Module Federation in Webpack 5 The Microfrontend Revolution: Module Federation with Angular Dynamic Module Federation with Angular Building A Plugin-based Workflow Designer With Angular and Module Federation Getting Out of Version-Mismatch-Hell with Module Federation Using Module Federation with (Nx) Monorepos and [&hellip;]<\/p>\n","protected":false},"author":9,"featured_media":6176,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_price":"","_stock":"","_tribe_ticket_header":"","_tribe_default_ticket_provider":"","_ticket_start_date":"","_ticket_end_date":"","_tribe_ticket_show_description":"","_tribe_ticket_show_not_going":false,"_tribe_ticket_use_global_stock":"","_tribe_ticket_global_stock_level":"","_global_stock_mode":"","_global_stock_cap":"","_tribe_rsvp_for_event":"","_tribe_ticket_going_count":"","_tribe_ticket_not_going_count":"","_tribe_tickets_list":"[]","_tribe_ticket_has_attendee_info_fields":false,"footnotes":""},"categories":[18],"tags":[],"class_list":["post-6180","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","post_series-module-federation"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Module Federation with Angular&#039;s Standalone Components - ANGULARarchitects<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Module Federation with Angular&#039;s Standalone Components\" \/>\n<meta property=\"og:description\" content=\"How to use Standalone Components with Module Federation? How to group several Standalone Components and expose them together?\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/\" \/>\n<meta property=\"og:site_name\" content=\"ANGULARarchitects\" \/>\n<meta property=\"article:published_time\" content=\"2022-05-07T18:08:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-01-19T14:37:29+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2022\/05\/social.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"800\" \/>\n\t<meta property=\"og:image:height\" content=\"418\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Manfred Steyer, GDE\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@daniel\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Manfred Steyer, GDE\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/\"},\"author\":{\"name\":\"Manfred Steyer, GDE\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/15628efa7af4475ffaaeeb26c5112951\"},\"headline\":\"Module Federation with Angular&#8217;s Standalone Components\",\"datePublished\":\"2022-05-07T18:08:00+00:00\",\"dateModified\":\"2024-01-19T14:37:29+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/\"},\"wordCount\":794,\"publisher\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2022\/05\/shutterstock-393065488.jpg\",\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/\",\"name\":\"Module Federation with Angular's Standalone Components - ANGULARarchitects\",\"isPartOf\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2022\/05\/shutterstock-393065488.jpg\",\"datePublished\":\"2022-05-07T18:08:00+00:00\",\"dateModified\":\"2024-01-19T14:37:29+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/#primaryimage\",\"url\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2022\/05\/shutterstock-393065488.jpg\",\"contentUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2022\/05\/shutterstock-393065488.jpg\",\"width\":1000,\"height\":667},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.angulararchitects.io\/en\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Module Federation with Angular&#8217;s Standalone Components\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#website\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/\",\"name\":\"ANGULARarchitects\",\"description\":\"AngularArchitects.io\",\"publisher\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.angulararchitects.io\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\",\"name\":\"ANGULARarchitects\",\"alternateName\":\"SOFTWAREarchitects\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg\",\"contentUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg\",\"width\":644,\"height\":216,\"caption\":\"ANGULARarchitects\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/github.com\/angular-architects\",\"https:\/\/www.linkedin.com\/company\/angular-architects\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/15628efa7af4475ffaaeeb26c5112951\",\"name\":\"Manfred Steyer, GDE\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/a0b59539674d8b71ea1c1f4764b11244b5f499203f1d11b40f37d8f3f90be033?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/a0b59539674d8b71ea1c1f4764b11244b5f499203f1d11b40f37d8f3f90be033?s=96&d=mm&r=g\",\"caption\":\"Manfred Steyer, GDE\"},\"sameAs\":[\"https:\/\/x.com\/daniel\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Module Federation with Angular's Standalone Components - ANGULARarchitects","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/","og_locale":"en_US","og_type":"article","og_title":"Module Federation with Angular's Standalone Components","og_description":"How to use Standalone Components with Module Federation? How to group several Standalone Components and expose them together?","og_url":"https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/","og_site_name":"ANGULARarchitects","article_published_time":"2022-05-07T18:08:00+00:00","article_modified_time":"2024-01-19T14:37:29+00:00","og_image":[{"width":800,"height":418,"url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2022\/05\/social.jpg","type":"image\/jpeg"}],"author":"Manfred Steyer, GDE","twitter_card":"summary_large_image","twitter_creator":"@daniel","twitter_misc":{"Written by":"Manfred Steyer, GDE","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/#article","isPartOf":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/"},"author":{"name":"Manfred Steyer, GDE","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/15628efa7af4475ffaaeeb26c5112951"},"headline":"Module Federation with Angular&#8217;s Standalone Components","datePublished":"2022-05-07T18:08:00+00:00","dateModified":"2024-01-19T14:37:29+00:00","mainEntityOfPage":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/"},"wordCount":794,"publisher":{"@id":"https:\/\/www.angulararchitects.io\/en\/#organization"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/#primaryimage"},"thumbnailUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2022\/05\/shutterstock-393065488.jpg","inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/","url":"https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/","name":"Module Federation with Angular's Standalone Components - ANGULARarchitects","isPartOf":{"@id":"https:\/\/www.angulararchitects.io\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/#primaryimage"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/#primaryimage"},"thumbnailUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2022\/05\/shutterstock-393065488.jpg","datePublished":"2022-05-07T18:08:00+00:00","dateModified":"2024-01-19T14:37:29+00:00","breadcrumb":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/#primaryimage","url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2022\/05\/shutterstock-393065488.jpg","contentUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2022\/05\/shutterstock-393065488.jpg","width":1000,"height":667},{"@type":"BreadcrumbList","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/module-federation-with-angulars-standalone-components\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.angulararchitects.io\/en\/"},{"@type":"ListItem","position":2,"name":"Module Federation with Angular&#8217;s Standalone Components"}]},{"@type":"WebSite","@id":"https:\/\/www.angulararchitects.io\/en\/#website","url":"https:\/\/www.angulararchitects.io\/en\/","name":"ANGULARarchitects","description":"AngularArchitects.io","publisher":{"@id":"https:\/\/www.angulararchitects.io\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.angulararchitects.io\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.angulararchitects.io\/en\/#organization","name":"ANGULARarchitects","alternateName":"SOFTWAREarchitects","url":"https:\/\/www.angulararchitects.io\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/","url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg","contentUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg","width":644,"height":216,"caption":"ANGULARarchitects"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/github.com\/angular-architects","https:\/\/www.linkedin.com\/company\/angular-architects\/"]},{"@type":"Person","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/15628efa7af4475ffaaeeb26c5112951","name":"Manfred Steyer, GDE","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/a0b59539674d8b71ea1c1f4764b11244b5f499203f1d11b40f37d8f3f90be033?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a0b59539674d8b71ea1c1f4764b11244b5f499203f1d11b40f37d8f3f90be033?s=96&d=mm&r=g","caption":"Manfred Steyer, GDE"},"sameAs":["https:\/\/x.com\/daniel"]}]}},"_links":{"self":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/6180","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/users\/9"}],"replies":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/comments?post=6180"}],"version-history":[{"count":2,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/6180\/revisions"}],"predecessor-version":[{"id":24275,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/6180\/revisions\/24275"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/media\/6176"}],"wp:attachment":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/media?parent=6180"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/categories?post=6180"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/tags?post=6180"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}