[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"categories-en":3,"post:\u002Fpost\u002Fangular-micro-frontends-how-to-scale-large-applications-and-eliminate-monolithic-build-times-with-module-federation":37},[4,11,17,24,30],{"id":5,"slug":6,"name":7,"colorHex":8,"iconName":9,"postCount":10},"0e2c1225-f78a-4c20-8c93-998ab9dc93b9","frontend","Frontend","#40484f",null,25,{"id":12,"slug":13,"name":14,"colorHex":15,"iconName":9,"postCount":16},"bc8df70e-b7fb-4d89-a80c-fd458d36d58c","code-development","Code & Development","#8b5cf6",23,{"id":18,"slug":19,"name":20,"colorHex":21,"iconName":22,"postCount":23},"550e8400-e29b-41d4-a716-446655440001","inteligencia-artificial","Artificial Intelligence","#6366f1","brain",14,{"id":25,"slug":26,"name":27,"colorHex":28,"iconName":9,"postCount":29},"ea63b69c-2eb4-4100-81f3-70ce52d33743","tech-news","Tech News","#e50606",4,{"id":31,"slug":32,"name":33,"colorHex":34,"iconName":35,"postCount":36},"550e8400-e29b-41d4-a716-446655440017","how-to-guides","How-To & Guides","#be123c","book-open",2,{"post":38,"related":592,"translations":658,"resolved":9},{"id":39,"slug":40,"title":41,"excerpt":42,"image":43,"featured":44,"groupId":45,"publishedAt":46,"readingTime":47,"views":48,"author":49,"category":51,"tags":52,"contentJson":62,"metaTitle":589,"metaDescription":590,"updatedAt":591},"86e804a8-71f4-4985-a013-d6c033e28967","angular-micro-frontends-how-to-scale-large-applications-and-eliminate-monolithic-build-times-with-module-federation","Angular Micro-frontends: How to Scale Large Applications and Eliminate Monolithic Build Times with Module Federation","Discover how to break down large Angular monoliths using Module Federation to enable independent deployments and seamless team scaling.","https:\u002F\u002Fmfgiomkkbihnlpfdxwrt.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fblog-assets\u002Fmedia\u002Ffeatured\u002F1774499855857-featured-x9ugz1.jpg",false,"a029aa9b-573b-4e5b-921b-eaecea6e989f","2026-06-21T06:41:59.230237+00:00",10,0,{"name":50,"avatar":9},"Genildo Souza",{"slug":6,"name":7,"color":8},[53,56,59],{"slug":54,"name":55},"angular","Angular",{"slug":57,"name":58},"javascript","JavaScript",{"slug":60,"name":61},"typescript","TypeScript",{"type":63,"content":64},"doc",[65,76,84,97,110,116,125,131,137,149,167,175,187,193,201,207,214,236,244,250,257,275,283,289,296,300,308,314,326,333,354,362,368,377,383,390,398,404,411,419,425,432,446,454,460,468,475,483,489,496,504,510,516,536,544,550,557,563,576,586],{"type":66,"attrs":67},"summaryBox",{"id":68,"items":69,"title":75},"sum_t0d3jnh4",[70,71,72,73,74],"Micro-frontends solve monolithic scaling issues by allowing independent development, deployment, and builds for different teams.","Module Federation enables Angular apps to share modules at runtime, allowing separate applications to function as a single cohesive unit.","The Shell application acts as an orchestrator that loads remote micro-frontends on demand via the Angular router.","Setting shared dependencies to singleton: true is critical to prevent code duplication and maintain a single instance of Angular.","Communication between independent micro-frontends should be managed through an event bus pattern to keep modules decoupled.","Angular Micro-frontends Architecture",{"type":77,"attrs":78,"content":80},"paragraph",{"id":79},"p_bxdoxvoy",[81],{"text":82,"type":83},"Your Angular app started small. About 15 components, two routes, an authentication module. The build took seconds. Merges were smooth. Life was good.","text",{"type":77,"attrs":85,"content":87},{"id":86},"p_ilh0zh2m",[88,90,95],{"text":89,"type":83},"Six months later, the project has 200 components. Three squads working on the same repository. The ",{"text":91,"type":83,"marks":92},"ng build",[93],{"type":94},"code",{"text":96,"type":83}," takes 4 minutes. Every merge becomes a diplomatic negotiation. And the worst part: when the product team breaks something in the checkout, the catalog team finds out on Friday night.",{"type":77,"attrs":98,"content":100},{"id":99},"p_rf8lqs1n",[101,103,108],{"text":102,"type":83},"This isn't a bad code problem. It's an ",{"text":104,"type":83,"marks":105},"architecture",[106],{"type":107},"bold",{"text":109,"type":83}," problem. When three teams share the same build, the same deploy, and the same bundle — any change from one affects all the others.",{"type":77,"attrs":111,"content":113},{"id":112},"p_gj89zr33",[114],{"text":115,"type":83},"Micro-frontends exist to solve exactly this.",{"type":117,"attrs":118,"content":120},"heading",{"id":119,"level":36},"h_v8h35d7m",[121],{"text":122,"type":83,"marks":123},"What are micro-frontends (without the jargon)",[124],{"type":107},{"type":77,"attrs":126,"content":128},{"id":127},"p_as1x3b67",[129],{"text":130,"type":83},"If you've heard of microservices on the backend, micro-frontends are the same idea applied to the frontend: instead of one giant monolithic app, you split the application into smaller, independent pieces. Each piece has its own repository, its own build, and its own deploy.",{"type":77,"attrs":132,"content":134},{"id":133},"p_ltt22nqk",[135],{"text":136,"type":83},"In Angular, this means the product module can be a separate Angular app. The orders module, another. The authentication module, another. Each one developed, tested, and published by different teams — without stepping on anyone's toes.",{"type":77,"attrs":138,"content":140},{"id":139},"p_vlyfbjgf",[141,143,147],{"text":142,"type":83},"A main application (the ",{"text":144,"type":83,"marks":145},"Shell",[146],{"type":107},{"text":148,"type":83},") orchestrates everything: it loads the micro-frontends on demand, handles global routing, and ensures the end user sees a unique and cohesive experience — without realizing that underneath there are several independent apps.",{"type":150,"attrs":151},"speedCards",{"id":152,"cards":153,"title":165,"caption":166},"speed_vpce7d8m",[154,157,161],{"label":144,"value":155,"detail":156},"🏠","A aplicação host que orquestra tudo. Cuida do roteamento global e carrega os micro-frontends dinamicamente.",{"label":158,"value":159,"detail":160},"Remotes","📦","Os micro-frontends independentes. Cada um é um app Angular completo, com seu próprio build e deploy.",{"label":162,"value":163,"detail":164},"Shared","🔗","Dependências compartilhadas entre todos — Angular core, RxJS, design system. Carregadas uma vez, usadas por todos.","The three pillars of a micro-frontend architecture","Shell + Remotes + Shared = micro-frontends that work as a single app for the end user.",{"type":117,"attrs":168,"content":170},{"id":169,"level":36},"h_sdy8er11",[171],{"text":172,"type":83,"marks":173},"Module Federation: the technology that makes it all work",[174],{"type":107},{"type":77,"attrs":176,"content":178},{"id":177},"p_n3fvg0ae",[179,181,185],{"text":180,"type":83},"The magic behind micro-frontends in Angular has a name: ",{"text":182,"type":83,"marks":183},"Module Federation",[184],{"type":107},{"text":186,"type":83},". It's a Webpack 5 feature that allows different builds to share modules at runtime. In practical terms: the product app can import code from the orders app without the two having been compiled together.",{"type":77,"attrs":188,"content":190},{"id":189},"p_vpwq3bgj",[191],{"text":192,"type":83},"Let's see how this is set up in practice. First, the Shell configuration — the app that will orchestrate everything:",{"type":194,"attrs":195,"content":198},"codeBlock",{"id":196,"language":57,"highlighted":197},"code_yx3zv7h7","\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F webpack.config.js — configuração do Shell\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">const\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> ModuleFederationPlugin\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> require\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"@module-federation\u002Fwebpack\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">module\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">exports\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  plugins: [\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">    new\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> ModuleFederationPlugin\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">({\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      name: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"shell\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      remotes: {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">        \u002F\u002F Cada micro-frontend é registrado aqui\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">        \"mfe-products\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"mfeProducts@http:\u002F\u002Flocalhost:4201\u002FremoteEntry.js\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">        \"mfe-orders\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"mfeOrders@http:\u002F\u002Flocalhost:4202\u002FremoteEntry.js\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      },\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      shared: {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">        \u002F\u002F Dependências que todos compartilham — carregadas uma vez só\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">        \"@angular\u002Fcore\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: { singleton: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, strictVersion: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> },\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">        \"@angular\u002Fcommon\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: { singleton: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, strictVersion: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> },\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">        \"@angular\u002Frouter\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: { singleton: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, strictVersion: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    })\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  ]\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">};\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",[199],{"text":200,"type":83},"\u002F\u002F webpack.config.js — configuração do Shell\nconst ModuleFederationPlugin = require(\"@module-federation\u002Fwebpack\");\n\nmodule.exports = {\n  plugins: [\n    new ModuleFederationPlugin({\n      name: \"shell\",\n      remotes: {\n        \u002F\u002F Cada micro-frontend é registrado aqui\n        \"mfe-products\": \"mfeProducts@http:\u002F\u002Flocalhost:4201\u002FremoteEntry.js\",\n        \"mfe-orders\": \"mfeOrders@http:\u002F\u002Flocalhost:4202\u002FremoteEntry.js\"\n      },\n      shared: {\n        \u002F\u002F Dependências que todos compartilham — carregadas uma vez só\n        \"@angular\u002Fcore\": { singleton: true, strictVersion: true },\n        \"@angular\u002Fcommon\": { singleton: true, strictVersion: true },\n        \"@angular\u002Frouter\": { singleton: true, strictVersion: true }\n      }\n    })\n  ]\n};",{"type":77,"attrs":202,"content":204},{"id":203},"p_hkzs46dk",[205],{"text":206,"type":83},"Now, the product micro-frontend configuration — the app that will be loaded remotely:",{"type":194,"attrs":208,"content":211},{"id":209,"language":57,"highlighted":210},"code_c467ooub","\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F webpack.config.js — configuração do micro-frontend de produtos\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">const\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> ModuleFederationPlugin\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> require\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"@module-federation\u002Fwebpack\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">module\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">exports\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  plugins: [\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">    new\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> ModuleFederationPlugin\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">({\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      name: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"mfeProducts\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      filename: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"remoteEntry.js\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F o ponto de entrada que o Shell vai carregar\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      exposes: {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">        \u002F\u002F O que esse micro-frontend disponibiliza pro mundo\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">        \".\u002FProductsModule\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\".\u002Fsrc\u002Fapp\u002Fproducts\u002Fproducts.module.ts\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      },\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      shared: {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">        \"@angular\u002Fcore\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: { singleton: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, strictVersion: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> },\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">        \"@angular\u002Fcommon\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: { singleton: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, strictVersion: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    })\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  ]\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">};\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",[212],{"text":213,"type":83},"\u002F\u002F webpack.config.js — configuração do micro-frontend de produtos\nconst ModuleFederationPlugin = require(\"@module-federation\u002Fwebpack\");\n\nmodule.exports = {\n  plugins: [\n    new ModuleFederationPlugin({\n      name: \"mfeProducts\",\n      filename: \"remoteEntry.js\", \u002F\u002F o ponto de entrada que o Shell vai carregar\n      exposes: {\n        \u002F\u002F O que esse micro-frontend disponibiliza pro mundo\n        \".\u002FProductsModule\": \".\u002Fsrc\u002Fapp\u002Fproducts\u002Fproducts.module.ts\"\n      },\n      shared: {\n        \"@angular\u002Fcore\": { singleton: true, strictVersion: true },\n        \"@angular\u002Fcommon\": { singleton: true, strictVersion: true }\n      }\n    })\n  ]\n};",{"type":215,"attrs":216,"content":219},"callout",{"id":217,"type":218,"title":9},"call_86qqzpl8","info",[220],{"type":77,"attrs":221,"content":223},{"id":222},"p_bebx9er4",[224,228,230,234],{"text":225,"type":83,"marks":226},"The singleton: true in shared dependencies is critical.",[227],{"type":107},{"text":229,"type":83}," Without this, each micro-frontend would load its own copy of Angular — duplicating code, breaking dependency injection, and bloating the bundle. With ",{"text":231,"type":83,"marks":232},"singleton: true",[233],{"type":94},{"text":235,"type":83},", everyone shares the same instance.",{"type":117,"attrs":237,"content":239},{"id":238,"level":36},"h_698hdyhn",[240],{"text":241,"type":83,"marks":242},"The routing that connects everything",[243],{"type":107},{"type":77,"attrs":245,"content":247},{"id":246},"p_ww9axomj",[248],{"text":249,"type":83},"With Module Federation configured, the next step is to connect the micro-frontends to the Angular router. This is where it gets elegant: the Shell loads each micro-frontend on demand, when the user navigates to that route.",{"type":194,"attrs":251,"content":254},{"id":252,"language":60,"highlighted":253},"code_ol4b7s9z","\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F app-routing.module.ts — Shell\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">import\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> { loadRemoteModule } \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">from\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '@angular-architects\u002Fmodule-federation'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">const\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> routes\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> Routes\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> [\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    path: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'products'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">    loadChildren\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: () \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=>\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> loadRemoteModule\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">({\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      type: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'module'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      remoteEntry: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'http:\u002F\u002Flocalhost:4201\u002FremoteEntry.js'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      exposedModule: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'.\u002FProductsModule'\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    }).\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">then\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">m\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =>\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> m.ProductsModule)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  },\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    path: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'orders'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">    loadChildren\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: () \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=>\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> loadRemoteModule\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">({\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      type: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'module'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      remoteEntry: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'http:\u002F\u002Flocalhost:4202\u002FremoteEntry.js'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      exposedModule: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'.\u002FOrdersModule'\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    }).\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">then\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">m\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =>\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> m.OrdersModule)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  },\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  { path: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">''\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, redirectTo: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'\u002Fproducts'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, pathMatch: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'full'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">];\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",[255],{"text":256,"type":83},"\u002F\u002F app-routing.module.ts — Shell\nimport { loadRemoteModule } from '@angular-architects\u002Fmodule-federation';\n\nconst routes: Routes = [\n  {\n    path: 'products',\n    loadChildren: () => loadRemoteModule({\n      type: 'module',\n      remoteEntry: 'http:\u002F\u002Flocalhost:4201\u002FremoteEntry.js',\n      exposedModule: '.\u002FProductsModule'\n    }).then(m => m.ProductsModule)\n  },\n  {\n    path: 'orders',\n    loadChildren: () => loadRemoteModule({\n      type: 'module',\n      remoteEntry: 'http:\u002F\u002Flocalhost:4202\u002FremoteEntry.js',\n      exposedModule: '.\u002FOrdersModule'\n    }).then(m => m.OrdersModule)\n  },\n  { path: '', redirectTo: '\u002Fproducts', pathMatch: 'full' }\n];",{"type":77,"attrs":258,"content":260},{"id":259},"p_3bsp2019",[261,263,267,269,273],{"text":262,"type":83},"Notice: ",{"text":264,"type":83,"marks":265},"loadRemoteModule",[266],{"type":94},{"text":268,"type":83}," works like the ",{"text":270,"type":83,"marks":271},"loadChildren",[272],{"type":94},{"text":274,"type":83}," you already know from lazy loading — but instead of loading a local module, it fetches a module from another server. To the Angular Router, it's transparent. To the user, it's invisible.",{"type":117,"attrs":276,"content":278},{"id":277,"level":36},"h_7vi1aitn",[279],{"text":280,"type":83,"marks":281},"Dynamic loading: don't load what the user doesn't need",[282],{"type":107},{"type":77,"attrs":284,"content":286},{"id":285},"p_v6r404wj",[287],{"text":288,"type":83},"Lazy routing already solves part of the performance problem. But in large apps, you need more control. A dynamic loading service prevents the same micro-frontend from being downloaded twice and handles network failures:",{"type":194,"attrs":290,"content":293},{"id":291,"language":60,"highlighted":292},"code_m7jxpeos","\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">@\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Injectable\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">({ providedIn: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'root'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> })\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">export\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> class\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> DynamicModuleService\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">  private\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\"> loadedModules\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> new\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> Set\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">&#x3C;\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">>();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">  async\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> loadModule\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">    remoteName\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> string\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">    exposedModule\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> string\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">    remoteEntry\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> string\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  ) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">    const\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> moduleKey\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> `${\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">remoteName\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}-${\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">exposedModule\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}`\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">    if\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">this\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.loadedModules.\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">has\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(moduleKey)) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">      return\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">; \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F já carregou, não busca de novo\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">    try\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">      await\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> loadRemoteModule\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">({ type: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'module'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, remoteEntry, exposedModule });\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">      this\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.loadedModules.\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">add\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(moduleKey);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    } \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">catch\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (error) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      console.\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">error\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`Falha ao carregar ${\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">moduleKey\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:`\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, error);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">      throw\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> error; \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F deixa o componente de fallback cuidar\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",[294],{"text":295,"type":83},"@Injectable({ providedIn: 'root' })\nexport class DynamicModuleService {\n  private loadedModules = new Set\u003Cstring>();\n\n  async loadModule(\n    remoteName: string,\n    exposedModule: string,\n    remoteEntry: string\n  ) {\n    const moduleKey = `${remoteName}-${exposedModule}`;\n\n    if (this.loadedModules.has(moduleKey)) {\n      return; \u002F\u002F já carregou, não busca de novo\n    }\n\n    try {\n      await loadRemoteModule({ type: 'module', remoteEntry, exposedModule });\n      this.loadedModules.add(moduleKey);\n    } catch (error) {\n      console.error(`Falha ao carregar ${moduleKey}:`, error);\n      throw error; \u002F\u002F deixa o componente de fallback cuidar\n    }\n  }\n}",{"type":297,"attrs":298},"newsletterBlock",{"id":299},"nl_625abgg8",{"type":117,"attrs":301,"content":303},{"id":302,"level":36},"h_sxddufio",[304],{"text":305,"type":83,"marks":306},"Communication between micro-frontends",[307],{"type":107},{"type":77,"attrs":309,"content":311},{"id":310},"p_gyn1342g",[312],{"text":313,"type":83},"If each micro-frontend is independent, how do they talk to each other? The user logs in to the authentication module — how does the orders module find out?",{"type":77,"attrs":315,"content":317},{"id":316},"p_t12nolg0",[318,320,324],{"text":319,"type":83},"The answer is a pattern the backend has been using for years: ",{"text":321,"type":83,"marks":322},"event bus",[323],{"type":107},{"text":325,"type":83},". A central service that publishes and receives typed events. No micro-frontend knows about the other directly — they only know about the events.",{"type":194,"attrs":327,"content":330},{"id":328,"language":60,"highlighted":329},"code_s8noifng","\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F Tipos dos eventos — o contrato entre micro-frontends\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">interface\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> EventPayloadMap\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">  'USER_LOGGED_IN'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> { \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">userId\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> string\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">; \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">role\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> string\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> };\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">  'CART_UPDATED'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> { \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">itemCount\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> number\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">; \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">total\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> number\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> };\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">  'NAVIGATION_REQUESTED'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> { \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">path\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> string\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">; \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">params\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">?:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> any\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> };\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">@\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Injectable\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">({ providedIn: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'root'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> })\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">export\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> class\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> MicroFrontendEventBus\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">  private\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\"> bus\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> new\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> Subject\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">&#x3C;{ \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">type\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> string\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">; \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">payload\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> any\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">; \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">source\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> string\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> }>();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">  \u002F\u002F Publicar evento — type-safe\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">  publish\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">&#x3C;\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">T\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> extends\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> keyof\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> EventPayloadMap\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">>(\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">    type\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> T\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">    payload\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> EventPayloadMap\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">[\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">T\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">],\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">    source\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> string\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  )\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> void\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">    this\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.bus.\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">next\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">({ type, payload, source });\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">  \u002F\u002F Ouvir evento — type-safe\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">  on\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">&#x3C;\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">T\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> extends\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> keyof\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> EventPayloadMap\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">>(\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">    eventType\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> T\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  )\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> Observable\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">&#x3C;\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">EventPayloadMap\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">[\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">T\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">]> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">    return\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> this\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.bus.\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">pipe\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">      filter\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">event\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =>\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> event.type \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">===\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> eventType),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">      map\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">event\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =>\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> event.payload \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">as\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> EventPayloadMap\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">[\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">T\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">])\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    );\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",[331],{"text":332,"type":83},"\u002F\u002F Tipos dos eventos — o contrato entre micro-frontends\ninterface EventPayloadMap {\n  'USER_LOGGED_IN': { userId: string; role: string };\n  'CART_UPDATED': { itemCount: number; total: number };\n  'NAVIGATION_REQUESTED': { path: string; params?: any };\n}\n\n@Injectable({ providedIn: 'root' })\nexport class MicroFrontendEventBus {\n  private bus = new Subject\u003C{ type: string; payload: any; source: string }>();\n\n  \u002F\u002F Publicar evento — type-safe\n  publish\u003CT extends keyof EventPayloadMap>(\n    type: T,\n    payload: EventPayloadMap[T],\n    source: string\n  ): void {\n    this.bus.next({ type, payload, source });\n  }\n\n  \u002F\u002F Ouvir evento — type-safe\n  on\u003CT extends keyof EventPayloadMap>(\n    eventType: T\n  ): Observable\u003CEventPayloadMap[T]> {\n    return this.bus.pipe(\n      filter(event => event.type === eventType),\n      map(event => event.payload as EventPayloadMap[T])\n    );\n  }\n}",{"type":215,"attrs":334,"content":337},{"id":335,"type":336,"title":9},"call_xqlwsmtr","tip",[338],{"type":77,"attrs":339,"content":341},{"id":340},"p_6u89dnqa",[342,346,348,352],{"text":343,"type":83,"marks":344},"The EventPayloadMap is the secret.",[345],{"type":107},{"text":347,"type":83}," It works like a contract: every micro-frontend knows which events exist and what the format of each one is. If someone changes the payload of ",{"text":349,"type":83,"marks":350},"CART_UPDATED",[351],{"type":94},{"text":353,"type":83},", TypeScript warns everywhere that consumes this event. No runtime surprises.",{"type":117,"attrs":355,"content":357},{"id":356,"level":36},"h_1xa5rmry",[358],{"text":359,"type":83,"marks":360},"The mistakes everyone makes (and how to avoid them)",[361],{"type":107},{"type":77,"attrs":363,"content":365},{"id":364},"p_20vcf69p",[366],{"text":367,"type":83},"Micro-frontends solve real problems, but create new ones if implemented carelessly. These are the three most common mistakes — and all three I've seen in production.",{"type":117,"attrs":369,"content":372},{"id":370,"level":371},"h_7cg8bd81",3,[373],{"text":374,"type":83,"marks":375},"1. Not having a fallback when a micro-frontend fails",[376],{"type":107},{"type":77,"attrs":378,"content":380},{"id":379},"p_nsjqd5qt",[381],{"text":382,"type":83},"If the product micro-frontend server goes down, what does the user see? If the answer is \"a white screen,\" you have a problem. Every remote micro-frontend needs a fallback component:",{"type":194,"attrs":384,"content":387},{"id":385,"language":60,"highlighted":386},"code_9lyzak96","\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">@\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Component\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">({\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  template: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">    &#x3C;div class=\"error-fallback\">\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">      &#x3C;h3>Este módulo está temporariamente indisponível&#x3C;\u002Fh3>\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">      &#x3C;p>Estamos trabalhando pra restaurar. Tente novamente em alguns minutos.&#x3C;\u002Fp>\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">      &#x3C;button (click)=\"retry()\">Tentar novamente&#x3C;\u002Fbutton>\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">    &#x3C;\u002Fdiv>\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">  `\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">})\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">export\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> class\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> MicroFrontendFallbackComponent\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">  retry\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">() {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    window.location.\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">reload\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",[388],{"text":389,"type":83},"@Component({\n  template: `\n    \u003Cdiv class=\"error-fallback\">\n      \u003Ch3>Este módulo está temporariamente indisponível\u003C\u002Fh3>\n      \u003Cp>Estamos trabalhando pra restaurar. Tente novamente em alguns minutos.\u003C\u002Fp>\n      \u003Cbutton (click)=\"retry()\">Tentar novamente\u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n  `\n})\nexport class MicroFrontendFallbackComponent {\n  retry() {\n    window.location.reload();\n  }\n}",{"type":117,"attrs":391,"content":393},{"id":392,"level":371},"h_fcth5irk",[394],{"text":395,"type":83,"marks":396},"2. Sharing global state between micro-frontends",[397],{"type":107},{"type":77,"attrs":399,"content":401},{"id":400},"p_z3kmhwjb",[402],{"text":403,"type":83},"The natural instinct is to create a global store that all micro-frontends access. Resist this instinct. Shared global state creates tight coupling — exactly what micro-frontends exist to eliminate. Each micro-frontend maintains its own state and communicates via events:",{"type":194,"attrs":405,"content":408},{"id":406,"language":60,"highlighted":407},"code_pwbs5qar","\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">@\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Injectable\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">export\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> class\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> BoundedContextService\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">  \u002F\u002F Cada micro-frontend mantém seu próprio estado\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">  private\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\"> localState\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> new\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> BehaviorSubject\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(initialState);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">  \u002F\u002F Comunica via eventos, nunca compartilha estado diretamente\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">  notifyDomainEvent\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">event\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> DomainEvent\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">)\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> void\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">    this\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.eventBus.\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">publish\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'DOMAIN_EVENT'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      context: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">this\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.contextName,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      event: event,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      timestamp: Date.\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">now\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    }, \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">this\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.contextName);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",[409],{"text":410,"type":83},"@Injectable()\nexport class BoundedContextService {\n  \u002F\u002F Cada micro-frontend mantém seu próprio estado\n  private localState = new BehaviorSubject(initialState);\n\n  \u002F\u002F Comunica via eventos, nunca compartilha estado diretamente\n  notifyDomainEvent(event: DomainEvent): void {\n    this.eventBus.publish('DOMAIN_EVENT', {\n      context: this.contextName,\n      event: event,\n      timestamp: Date.now()\n    }, this.contextName);\n  }\n}",{"type":117,"attrs":412,"content":414},{"id":413,"level":371},"h_p8p4e8ap",[415],{"text":416,"type":83,"marks":417},"3. Memory leaks in dynamic loading",[418],{"type":107},{"type":77,"attrs":420,"content":422},{"id":421},"p_9z80pbs4",[423],{"text":424,"type":83},"When a micro-frontend is loaded and then unloaded, it needs to clean up everything behind it — subscriptions, component references, timers. If it doesn't clean up, the app accumulates memory with every navigation:",{"type":194,"attrs":426,"content":429},{"id":427,"language":60,"highlighted":428},"code_ubgm0zbl","\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">@\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Injectable\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">export\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> class\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> MicroFrontendLifecycleService\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> implements\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> OnDestroy\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">  private\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\"> subscriptions\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> new\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> Map\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">&#x3C;\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Subscription\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">>();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">  private\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\"> loadedComponents\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> new\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> Map\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">&#x3C;\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">ComponentRef\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">&#x3C;\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">any\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">>>();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">  unloadMicroFrontend\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">name\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> string\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">)\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> void\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">    \u002F\u002F Destruir componente\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">    const\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> component\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> this\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.loadedComponents.\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">get\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(name);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">    if\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (component) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      component.\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">destroy\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">      this\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.loadedComponents.\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">delete\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(name);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">    \u002F\u002F Cancelar subscriptions\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">    const\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> sub\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> this\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.subscriptions.\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">get\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(name);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">    if\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (sub) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      sub.\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">unsubscribe\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">      this\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.subscriptions.\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">delete\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(name);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">  ngOnDestroy\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">()\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> void\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">    \u002F\u002F Na destruição do serviço, limpa tudo\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">    this\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.loadedComponents.\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">forEach\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">c\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =>\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> c.\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">destroy\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">());\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">    this\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.subscriptions.\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">forEach\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">s\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =>\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> s.\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">unsubscribe\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">());\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",[430],{"text":431,"type":83},"@Injectable()\nexport class MicroFrontendLifecycleService implements OnDestroy {\n  private subscriptions = new Map\u003Cstring, Subscription>();\n  private loadedComponents = new Map\u003Cstring, ComponentRef\u003Cany>>();\n\n  unloadMicroFrontend(name: string): void {\n    \u002F\u002F Destruir componente\n    const component = this.loadedComponents.get(name);\n    if (component) {\n      component.destroy();\n      this.loadedComponents.delete(name);\n    }\n\n    \u002F\u002F Cancelar subscriptions\n    const sub = this.subscriptions.get(name);\n    if (sub) {\n      sub.unsubscribe();\n      this.subscriptions.delete(name);\n    }\n  }\n\n  ngOnDestroy(): void {\n    \u002F\u002F Na destruição do serviço, limpa tudo\n    this.loadedComponents.forEach(c => c.destroy());\n    this.subscriptions.forEach(s => s.unsubscribe());\n  }\n}",{"type":215,"attrs":433,"content":435},{"id":434,"type":218,"title":9},"call_e5q8g8of",[436],{"type":77,"attrs":437,"content":439},{"id":438},"p_ov91dmzv",[440,444],{"text":441,"type":83,"marks":442},"Rule of thumb:",[443],{"type":107},{"text":445,"type":83}," if your app gets slower the more the user navigates between sections, there is likely a memory leak in the dynamic loading. Use Chrome DevTools → Memory → Heap Snapshot before and after navigating to identify the leak.",{"type":117,"attrs":447,"content":449},{"id":448,"level":36},"h_oox00s6r",[450],{"text":451,"type":83,"marks":452},"Performance: what to optimize first",[453],{"type":107},{"type":77,"attrs":455,"content":457},{"id":456},"p_btbfeec3",[458],{"text":459,"type":83},"Micro-frontends can improve or worsen your app's performance — it depends on how you configure dependency sharing and the loading strategy.",{"type":117,"attrs":461,"content":463},{"id":462,"level":371},"h_sgdw9hw4",[464],{"text":465,"type":83,"marks":466},"Import only what you use",[467],{"type":107},{"type":194,"attrs":469,"content":472},{"id":470,"language":60,"highlighted":471},"code_p1ket14c","\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F ❌ Evite — importar o Angular Material inteiro\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">import\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> { MaterialModule } \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">from\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '.\u002Fmaterial.module'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">; \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F tudo junto\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F ✅ Faça assim — só o que o micro-frontend precisa\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">import\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> { MatButtonModule } \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">from\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '@angular\u002Fmaterial\u002Fbutton'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">import\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> { MatCardModule } \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">from\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '@angular\u002Fmaterial\u002Fcard'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">import\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> { MatInputModule } \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">from\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '@angular\u002Fmaterial\u002Finput'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">@\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">NgModule\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">({\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  imports: [MatButtonModule, MatCardModule, MatInputModule]\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">})\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">export\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> class\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> ProductsModule\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> { }\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",[473],{"text":474,"type":83},"\u002F\u002F ❌ Evite — importar o Angular Material inteiro\nimport { MaterialModule } from '.\u002Fmaterial.module'; \u002F\u002F tudo junto\n\n\u002F\u002F ✅ Faça assim — só o que o micro-frontend precisa\nimport { MatButtonModule } from '@angular\u002Fmaterial\u002Fbutton';\nimport { MatCardModule } from '@angular\u002Fmaterial\u002Fcard';\nimport { MatInputModule } from '@angular\u002Fmaterial\u002Finput';\n\n@NgModule({\n  imports: [MatButtonModule, MatCardModule, MatInputModule]\n})\nexport class ProductsModule { }",{"type":117,"attrs":476,"content":478},{"id":477,"level":371},"h_dt6ubgw9",[479],{"text":480,"type":83,"marks":481},"Intelligent preloading",[482],{"type":107},{"type":77,"attrs":484,"content":486},{"id":485},"p_zyfrlxs3",[487],{"text":488,"type":83},"Not every micro-frontend should be loaded on demand. The product module in an e-commerce site will be accessed by 90% of users — it makes sense to preload it. The reports module? Only during business hours. You can create a preload strategy based on context:",{"type":194,"attrs":490,"content":493},{"id":491,"language":60,"highlighted":492},"code_hcgv8yq3","\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">@\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Injectable\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">export\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> class\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> SmartPreloadingStrategy\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> implements\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> PreloadingStrategy\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">  preload\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">route\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> Route\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">load\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> () \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=>\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> Observable\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">&#x3C;\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">any\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">>)\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> Observable\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">&#x3C;\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">any\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">    const\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> priority\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> route.data?.[\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'preload'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">];\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">    if\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (priority \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">===\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> 'high'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">return\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> load\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(); \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F sempre pré-carrega\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">    if\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (priority \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">===\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> 'business-hours'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">      const\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> hour\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> new\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> Date\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">().\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">getHours\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">      if\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (hour \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">>=\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 9\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> &#x26;&#x26;\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> hour \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">&#x3C;=\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 17\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">return\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> load\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">    return\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> of\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">null\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">); \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F carrega só quando o usuário navegar\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F Nas rotas:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">const\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> routes\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> Routes\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> [\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    path: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'products'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    data: { preload: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'high'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> }, \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F sempre pré-carrega\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">    loadChildren\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: () \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=>\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> loadRemoteModule\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">({\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">...\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">})\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  },\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    path: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'reports'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    data: { preload: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'business-hours'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> }, \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F só no horário comercial\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">    loadChildren\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: () \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=>\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> loadRemoteModule\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">({\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">...\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">})\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">];\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",[494],{"text":495,"type":83},"@Injectable()\nexport class SmartPreloadingStrategy implements PreloadingStrategy {\n  preload(route: Route, load: () => Observable\u003Cany>): Observable\u003Cany> {\n    const priority = route.data?.['preload'];\n\n    if (priority === 'high') return load(); \u002F\u002F sempre pré-carrega\n    if (priority === 'business-hours') {\n      const hour = new Date().getHours();\n      if (hour >= 9 && hour \u003C= 17) return load();\n    }\n\n    return of(null); \u002F\u002F carrega só quando o usuário navegar\n  }\n}\n\n\u002F\u002F Nas rotas:\nconst routes: Routes = [\n  {\n    path: 'products',\n    data: { preload: 'high' }, \u002F\u002F sempre pré-carrega\n    loadChildren: () => loadRemoteModule({...})\n  },\n  {\n    path: 'reports',\n    data: { preload: 'business-hours' }, \u002F\u002F só no horário comercial\n    loadChildren: () => loadRemoteModule({...})\n  }\n];",{"type":117,"attrs":497,"content":499},{"id":498,"level":36},"h_4x57k9hd",[500],{"text":501,"type":83,"marks":502},"When NOT to use micro-frontends",[503],{"type":107},{"type":77,"attrs":505,"content":507},{"id":506},"p_lb3d9s3z",[508],{"text":509,"type":83},"This is the most important section of the article.",{"type":77,"attrs":511,"content":513},{"id":512},"p_37t0lcrw",[514],{"text":515,"type":83},"Micro-frontends add real complexity: more repositories to maintain, more CI\u002FCD pipelines to configure, more points of failure in production, more overhead of communication between modules. This complexity is only justified when the problem it solves is greater than the pain it creates.",{"type":215,"attrs":517,"content":519},{"id":518,"type":336,"title":9},"call_93lzinx9",[520],{"type":77,"attrs":521,"content":523},{"id":522},"p_qtu8mz5j",[524,528,530,534],{"text":525,"type":83,"marks":526},"Use micro-frontends when:",[527],{"type":107},{"text":529,"type":83}," multiple teams work on distinct domains of the same application and merge conflicts, build time, and deploy are delaying deliveries. ",{"text":531,"type":83,"marks":532},"Don't use when:",[533],{"type":107},{"text":535,"type":83}," the team is small, the app is manageable, and the real problem is code organization — which can be solved with lazy loading and good modularization, without needing Module Federation.",{"type":117,"attrs":537,"content":539},{"id":538,"level":36},"h_3wfk8e9m",[540],{"text":541,"type":83,"marks":542},"Migrating a monolith: where to start",[543],{"type":107},{"type":77,"attrs":545,"content":547},{"id":546},"p_5kzn6qas",[548],{"text":549,"type":83},"If you've decided that micro-frontends make sense for your context, don't try to migrate everything at once. The approach that works is incremental: keep the legacy routes working while adding the new federated routes alongside them.",{"type":194,"attrs":551,"content":554},{"id":552,"language":60,"highlighted":553},"code_vd4slwmo","\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F Migração incremental — rotas legadas e federadas coexistem\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">@\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">NgModule\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">({\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  imports: [RouterModule.\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">forRoot\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">([\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">    \u002F\u002F Rota legada — ainda funciona normalmente\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      path: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'legacy-products'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      component: ProductsComponent\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    },\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">    \u002F\u002F Nova rota federada — micro-frontend independente\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      path: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'products'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">      loadChildren\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: () \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=>\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> loadRemoteModule\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">({\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">        type: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'module'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">        remoteEntry: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'http:\u002F\u002Flocalhost:4201\u002FremoteEntry.js'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">        exposedModule: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'.\u002FProductsModule'\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      }).\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">then\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">m\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =>\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> m.ProductsModule)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  ])]\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">})\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">export\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> class\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> AppRoutingModule\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> { }\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",[555],{"text":556,"type":83},"\u002F\u002F Migração incremental — rotas legadas e federadas coexistem\n@NgModule({\n  imports: [RouterModule.forRoot([\n    \u002F\u002F Rota legada — ainda funciona normalmente\n    {\n      path: 'legacy-products',\n      component: ProductsComponent\n    },\n    \u002F\u002F Nova rota federada — micro-frontend independente\n    {\n      path: 'products',\n      loadChildren: () => loadRemoteModule({\n        type: 'module',\n        remoteEntry: 'http:\u002F\u002Flocalhost:4201\u002FremoteEntry.js',\n        exposedModule: '.\u002FProductsModule'\n      }).then(m => m.ProductsModule)\n    }\n  ])]\n})\nexport class AppRoutingModule { }",{"type":77,"attrs":558,"content":560},{"id":559},"p_ippjia0t",[561],{"text":562,"type":83},"When the product micro-frontend is stable in production, you remove the legacy route. One domain at a time. No big bang.",{"type":66,"attrs":564},{"id":565,"items":566,"title":575},"sum_24p7mnqh",[567,568,569,570,571,572,573,574],"Micro-frontends split a monolithic app into independent apps with their own build, deploy, and repository.","Module Federation (Webpack 5) allows separate builds to share modules at runtime — the Shell loads the Remotes on demand.","Communication via typed event bus — each micro-frontend knows the events, never the other micro-frontend directly.","Always implement fallbacks — if one micro-frontend goes down, the rest of the app should keep working.","Don't share global state — each micro-frontend maintains its state and communicates via events.","Clean up references and subscriptions when unloading micro-frontends — memory leaks are the most common silent bug.","Micro-frontends add real complexity. Only use them when multiple teams in distinct domains justify this complexity.","Migrate incrementally — legacy and federated routes coexist until the new micro-frontend is stable.","Takeaways from this article",{"type":577,"attrs":578},"promoBox",{"id":579,"title":580,"layout":581,"ctaHref":582,"eyebrow":55,"variant":583,"ctaLabel":584,"description":585},"promo_d2gbx1vf","Want to master modern Angular?","stacked","\u002Ftags\u002Fangular","default","Explorar","Signals, incremental hydration, new control flow — Angular has changed. Explore the other articles in the series to understand what changed and how to apply it.",{"type":77,"attrs":587},{"id":588},"p_xy2bt097","Angular Micro-frontends: Distributed Architecture Guide","Learn to scale Angular apps using Module Federation. Split your monolith into independent micro-frontends to improve build times and team velocity.","2026-08-24T14:53:53.315534+00:00",[593,611,626,640],{"id":594,"slug":595,"title":596,"excerpt":597,"image":598,"featured":44,"groupId":599,"publishedAt":600,"readingTime":601,"views":48,"author":602,"category":603,"tags":604},"841890b2-1a8c-43d4-b434-b94714705605","debugging-css-the-forgotten-margin-and-frontend-lessons","Debugging CSS: The Forgotten Margin and Frontend Lessons","A forgotten CSS property turned a minor layout glitch into a two-week ordeal. Learn how to avoid emotional debugging and fix complex UI issues faster.","https:\u002F\u002Fmfgiomkkbihnlpfdxwrt.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fblog-assets\u002Fmedia\u002Ffeatured\u002F1767745741814-featured-i6p1gc.jpeg","bcaf503a-15c1-4d28-8795-6ae3c2a3e06f","2026-08-02T16:09:35.153874+00:00",8,{"name":50,"avatar":9},{"slug":6,"name":7,"color":8},[605,608],{"slug":606,"name":607},"css","CSS",{"slug":609,"name":610},"performance","Performance",{"id":612,"slug":613,"title":614,"excerpt":615,"image":616,"featured":44,"groupId":617,"publishedAt":618,"readingTime":23,"views":48,"author":619,"category":620,"tags":621},"d5167910-cc5b-4fae-a2e8-d09adcf354b2","stop-using-usememo-wrong-a-practical-guide-to-react-performance","Stop Using useMemo Wrong: A Practical Guide to React Performance","Master React useMemo with this guide. Learn when to memoize, how to fix dependency array bugs, and why over-optimization can hurt your performance.","https:\u002F\u002Fmfgiomkkbihnlpfdxwrt.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fblog-assets\u002Fmedia\u002Ffeatured\u002F1769657096789-featured-r2q2sb.jpeg","a1c571c1-aa37-404d-ac67-f265c8a9985b","2026-07-08T23:34:34.563653+00:00",{"name":50,"avatar":9},{"slug":6,"name":7,"color":8},[622,623],{"slug":57,"name":58},{"slug":624,"name":625},"react","React",{"id":627,"slug":628,"title":629,"excerpt":630,"image":631,"featured":44,"groupId":632,"publishedAt":633,"readingTime":634,"views":48,"author":635,"category":636,"tags":637},"f1b5af43-20da-4150-a7c7-ef17675d1fee","css-animations-how-to-build-performant-professional-interfaces-without-messy-code","CSS Animations: How to Build Performant, Professional Interfaces Without Messy Code","Bring your web interfaces to life. Learn when to use CSS transitions versus keyframes and how to optimize your animations for peak performance.","https:\u002F\u002Fmfgiomkkbihnlpfdxwrt.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fblog-assets\u002Fmedia\u002Ffeatured\u002F1770952624247-featured-in9pir.jpeg","de5a7726-1227-4080-b572-9d91a37b207b","2026-07-04T03:00:53.174696+00:00",17,{"name":50,"avatar":9},{"slug":6,"name":7,"color":8},[638,639],{"slug":606,"name":607},{"slug":609,"name":610},{"id":641,"slug":642,"title":643,"excerpt":644,"image":645,"featured":44,"groupId":646,"publishedAt":647,"readingTime":648,"views":48,"author":649,"category":650,"tags":651},"0fb67226-b881-43f5-9970-3a1442aa4be1","a-guide-to-html-loading-strategies-that-will-speed-up-your-load-times","A Guide to HTML Loading Strategies That Will Speed Up Your Load Times","Stop blocking your renders and start delivering lightning-fast experiences to your users by mastering modern HTML script loading strategies.","https:\u002F\u002Fmfgiomkkbihnlpfdxwrt.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fblog-assets\u002Fmedia\u002Ffeatured\u002F1766637747576-featured-1bqmjq.png","be2f746b-fe22-4009-86a9-a80e33513e02","2026-06-19T21:24:56.768931+00:00",9,{"name":50,"avatar":9},{"slug":6,"name":7,"color":8},[652,653,654,655],{"slug":57,"name":58},{"slug":609,"name":610},{"slug":624,"name":625},{"slug":656,"name":657},"ssr","SSR",{"en":40,"pt":659},"angular-micro-frontends-arquitetura-distribuida"]