[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"categories-es":3,"post:\u002Fes\u002Fpost\u002Fmicrofrontends-con-angular-y-nx-lo-que-nadie-cuenta":36},[4,11,17,24,31],{"id":5,"slug":6,"name":7,"colorHex":8,"iconName":9,"postCount":10},"0e2c1225-f78a-4c20-8c93-998ab9dc93b9","frontend","Frontend","#40484f",null,14,{"id":12,"slug":13,"name":14,"colorHex":15,"iconName":9,"postCount":16},"bc8df70e-b7fb-4d89-a80c-fd458d36d58c","code-development","Programacion & Dev","#8b5cf6",6,{"id":18,"slug":19,"name":20,"colorHex":21,"iconName":22,"postCount":23},"550e8400-e29b-41d4-a716-446655440001","inteligencia-artificial","Inteligencia Artificial","#6366f1","brain",5,{"id":25,"slug":26,"name":27,"colorHex":28,"iconName":29,"postCount":30},"550e8400-e29b-41d4-a716-446655440017","how-to-guides","Guias & Tutoriales","#be123c","book-open",1,{"id":32,"slug":33,"name":34,"colorHex":35,"iconName":9,"postCount":30},"ea63b69c-2eb4-4100-81f3-70ce52d33743","tech-news","Noticias Tech","#e50606",{"post":37,"related":1353,"translations":1429,"resolved":9},{"id":38,"slug":39,"title":40,"excerpt":41,"image":42,"featured":43,"groupId":44,"publishedAt":45,"readingTime":46,"views":30,"author":47,"category":49,"tags":50,"contentJson":60,"metaTitle":1350,"metaDescription":1351,"updatedAt":1352},"52a34def-e823-42b8-ab7f-9f4e148d7016","microfrontends-con-angular-y-nx-lo-que-nadie-cuenta","Microfrontends con Angular y Nx: lo que nadie cuenta","Todo tutorial enseña a configurar microfrontends en minutos, pero pocos revelan el caos arquitectónico que surge tras meses de deploy en producción.","https:\u002F\u002Fmfgiomkkbihnlpfdxwrt.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fblog-assets\u002Fmedia\u002Ffeatured\u002F1785206853570-featured-zoyhgn.webp",false,"3368e1b2-b6de-4e94-a3d4-294fae8ade13","2026-08-11T03:52:00.507+00:00",16,{"name":48,"avatar":9},"Genildo Souza",{"slug":13,"name":14,"color":15},[51,54,57],{"slug":52,"name":53},"angular","Angular",{"slug":55,"name":56},"javascript","JavaScript",{"slug":58,"name":59},"typescript","TypeScript",{"type":61,"content":62},"doc",[63,74,82,84,92,101,107,113,120,141,149,150,156,162,179,201,211,221,249,250,256,263,269,277,284,292,312,313,319,325,331,339,346,372,373,379,385,411,418,425,426,432,438,446,453,485,486,492,498,505,512,538,539,545,760,780,786,931,932,938,944,952,959,975,976,984,991,1006,1007,1015,1022,1031,1032,1048,1055,1069,1070,1092,1101,1102,1123,1132,1133,1140,1141,1147,1157,1182,1188,1194,1213,1216,1224,1225,1231,1347],{"type":64,"attrs":65},"summaryBox",{"id":66,"items":67,"title":73},"sum_9dj9myqg",[68,69,70,71,72],"Los Microfrontends a menudo tardan tres meses en implementarse y nueve meses en estabilizarse debido a problemas de producción no previstos.","El intercambio de estado global entre remotes anula la independencia de los deploys, haciendo que el sistema sea acoplado y difícil de mantener.","Los conflictos de CSS entre remotes son problemas no deterministas que exigen el uso de namespaces rigurosos para evitar la fuga de estilos.","El uso de Nx con configuraciones estrictas de versionado es esencial para evitar fallos silenciosos causados por incompatibilidades de librerías.","Mantener versiones diferentes de Angular en un mismo monorepo Nx es inviable, siendo necesario realizar migraciones globales en todo el workspace.","Desafíos reales de Microfrontends con Angular",{"type":75,"attrs":76,"content":78},"paragraph",{"id":77},"p_lvlt2h2j",[79],{"text":80,"type":81},"Todo tutorial muestra cómo configurar el Module Federation en 20 minutos. Ninguno muestra lo que sucede 6 meses después en producción: el CSS que se filtra entre remotes, la versión de Angular que tira abajo el shell, el estado compartido que hizo imposible el deploy independiente y el costo organizacional que el diagrama arquitectónico no captura.","text",{"type":83},"horizontalRule",{"type":85,"attrs":86,"content":89},"heading",{"id":87,"level":88},"h_9sne1pdm",2,[90],{"text":91,"type":81},"La realidad que el tutorial no muestra",{"type":75,"attrs":93,"content":95},{"id":94},"p_xripo1li",[96],{"text":97,"type":81,"marks":98},"El tutorial termina donde el problema comienza.",[99],{"type":100},"bold",{"type":75,"attrs":102,"content":104},{"id":103},"p_nzji425p",[105],{"text":106,"type":81},"La mayoría de los equipos que implementan microfrontends llegan a producción en 3 meses y pasan los siguientes 9 meses resolviendo problemas que ningún tutorial mencionó.",{"type":75,"attrs":108,"content":110},{"id":109},"p_7g3vwg2p",[111],{"text":112,"type":81},"El modelo es seductor: equipos independientes, deploys independientes, autonomía de tecnología. En la práctica, la independencia prometida tiene un costo que solo aparece cuando un equipo intenta subir una versión de Angular mientras otro aún está en el ciclo anterior. O cuando el CSS del remote de checkout comienza a afectar el layout del shell. O cuando descubres que el estado compartido que pusiste en un servicio global hizo que el deploy independiente fuera técnicamente imposible.",{"type":114,"attrs":115},"pullquote",{"id":116,"quote":117,"accent":118,"attribution":119},"pq_atgzd9bs","A arquitetura de microfrontends não falha no código. Falha nas fronteiras que você não definiu.","red","Microfrontends com Angular e Nx: o que ninguém conta",{"type":121,"attrs":122,"content":124},"blockquote",{"id":123},"quote_gehsdmec",[125],{"type":75,"attrs":126,"content":128},{"id":127},"p_heusukbt",[129,133,135,139],{"text":130,"type":81,"marks":131},"→ El número que importa",[132],{"type":100},{"text":134,"type":81}," En una encuesta con más de 20 proyectos de microfrontend de 2021-2023, el patrón era consistente: ",{"text":136,"type":81,"marks":137},"3 meses para implementar, 9 meses para estabilizar",[138],{"type":100},{"text":140,"type":81},". Los problemas de state compartido, CSS leaking y version mismatch no aparecen en demos; aparecen cuando los equipos comienzan a trabajar de forma genuinamente independiente.",{"type":75,"attrs":142,"content":144},{"id":143},"p_im70meu4",[145],{"text":146,"type":81,"marks":147},"La arquitectura de microfrontends no falla en el código. Falla en las fronteras que no definiste.",[148],{"type":100},{"type":83},{"type":85,"attrs":151,"content":153},{"id":152,"level":88},"h_sktc911w",[154],{"text":155,"type":81},"Los 5 problemas de producción",{"type":75,"attrs":157,"content":159},{"id":158},"p_7fbtv1me",[160],{"text":161,"type":81},"Lo que sucede 6 meses después del deploy.",{"type":75,"attrs":163,"content":165},{"id":164},"p_dr33z3om",[166,170,172,177],{"text":167,"type":81,"marks":168},"Problema 01 — Version mismatch — el crash silencioso:",[169],{"type":100},{"text":171,"type":81}," El equipo A usa Angular 21. El equipo B actualiza a Angular 22 con la nueva API de Signal Forms. El shell carga ambos. El Module Federation intenta reconciliar las versiones con ",{"text":173,"type":81,"marks":174},"singleton: true",[175],{"type":176},"code",{"text":178,"type":81},". A veces funciona. A veces el remote B falla sin un mensaje de error obvio.",{"type":75,"attrs":180,"content":182},{"id":181},"p_xsx78eft",[183,187,189,193,195,199],{"text":184,"type":81,"marks":185},"Problema 02 — CSS leaking — el estilo que no tiene fronteras:",[186],{"type":100},{"text":188,"type":81}," El remote de checkout define ",{"text":190,"type":81,"marks":191},".btn { background: red }",[192],{"type":176},{"text":194,"type":81}," sin scope. El shell tiene ",{"text":196,"type":81,"marks":197},".btn { background: blue }",[198],{"type":176},{"text":200,"type":81},". Dependiendo del orden de carga, uno sobrescribe al otro. En producción, el orden cambia con el caching. El bug es no determinista.",{"type":75,"attrs":202,"content":204},{"id":203},"p_bklwjnzf",[205,209],{"text":206,"type":81,"marks":207},"Problema 03 — Estado global — el deploy que no es independiente:",[208],{"type":100},{"text":210,"type":81}," Para compartir el usuario autenticado, alguien puso el estado en un NgRx Store compartido entre todos los remotes. Ahora, cualquier cambio en el shape del estado exige un deploy coordinado de todos los remotes. El deploy \"independiente\" dejó de ser independiente.",{"type":75,"attrs":212,"content":214},{"id":213},"p_flq7ykm3",[215,219],{"text":216,"type":81,"marks":217},"Problema 04 — DX en desarrollo — 4 terminales para 1 feature:",[218],{"type":100},{"text":220,"type":81}," Para ejecutar el feature de checkout localmente, el desarrollador necesita iniciar shell, catalog-mfe, admin-mfe y checkout-mfe. El tiempo de setup local se triplicó. La autonomía del equipo vino con un overhead de DX que nadie contabilizó.",{"type":75,"attrs":222,"content":224},{"id":223},"p_14tatuy1",[225,229,231,235,237,241,243,247],{"text":226,"type":81,"marks":227},"Problema 05 — Bundle size — el intercambio que no compartió:",[228],{"type":100},{"text":230,"type":81}," Cada remote empaquetó su propia copia de Angular Material porque la configuración de ",{"text":232,"type":81,"marks":233},"shared",[234],{"type":176},{"text":236,"type":81}," no incluyó las entradas secundarias (",{"text":238,"type":81,"marks":239},"@angular\u002Fmaterial\u002Fbutton",[240],{"type":176},{"text":242,"type":81},", ",{"text":244,"type":81,"marks":245},"@angular\u002Fmaterial\u002Fdialog",[246],{"type":176},{"text":248,"type":81},"). El bundle total quedó 3 veces más grande que el monolito original.",{"type":83},{"type":85,"attrs":251,"content":253},{"id":252,"level":88},"h_j0yk8ett",[254],{"text":255,"type":81},"Solución 01 — Version mismatch",{"type":85,"attrs":257,"content":260},{"id":258,"level":259},"h_40wu974z",3,[261],{"text":262,"type":81},"Gobernanza de versiones: Nx como árbitro",{"type":75,"attrs":264,"content":266},{"id":265},"p_mtv0xfn4",[267],{"text":268,"type":81},"El Module Federation permite versiones diferentes. Nx, por defecto, no lo permite, y esa restricción es un feature, no un bug.",{"type":270,"attrs":271,"content":274},"codeBlock",{"id":272,"language":58,"highlighted":273},"code_cdu9d5rv","\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 ❌ Configuração que causa crashes silenciosos\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F module-federation.config.ts (remote checkout)\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\"> const\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> config\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> ModuleFederationConfig\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\">  name: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'checkout'\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\">  exposes: {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">    '.\u002FModule'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'.\u002Fsrc\u002Fapp\u002Fremote-entry\u002Fentry.module.ts'\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\">  shared: {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">    \u002F\u002F ❌ singleton sem requiredVersion = aceita qualquer versão\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">    \u002F\u002F Se shell tem Angular 21 e remote tem Angular 22,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">    \u002F\u002F o Module Federation carrega a versão do shell silenciosamente\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\"> },\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\"> },\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>\u003C\u002Fcode>\u003C\u002Fpre>",[275],{"text":276,"type":81},"\u002F\u002F ❌ Configuração que causa crashes silenciosos\n\u002F\u002F module-federation.config.ts (remote checkout)\nexport const config: ModuleFederationConfig = {\n  name: 'checkout',\n  exposes: {\n    '.\u002FModule': '.\u002Fsrc\u002Fapp\u002Fremote-entry\u002Fentry.module.ts',\n  },\n  shared: {\n    \u002F\u002F ❌ singleton sem requiredVersion = aceita qualquer versão\n    \u002F\u002F Se shell tem Angular 21 e remote tem Angular 22,\n    \u002F\u002F o Module Federation carrega a versão do shell silenciosamente\n    '@angular\u002Fcore': { singleton: true },\n    '@angular\u002Fcommon': { singleton: true },\n  },\n};\n",{"type":270,"attrs":278,"content":281},{"id":279,"language":58,"highlighted":280},"code_k1zbef1c","\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 ✅ Governança de versão explícita com Nx\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F libs\u002Fshared-mf-config\u002Fbase.config.ts\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\"> { shareAll } \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">from\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '@nx\u002Fangular\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\">export\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> const\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> baseConfig\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\">  shared: {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">    \u002F\u002F ✅ requiredVersion: 'auto' lê do package.json do workspace\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">    \u002F\u002F strictVersion: true → falha se versão incompatível\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\">: {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\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\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\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\">      requiredVersion: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'auto'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F ← Nx resolve do root package.json\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:#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\">, requiredVersion: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'auto'\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\u002Fforms'\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\">, requiredVersion: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'auto'\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\">\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",[282],{"text":283,"type":81},"\u002F\u002F ✅ Governança de versão explícita com Nx\n\u002F\u002F libs\u002Fshared-mf-config\u002Fbase.config.ts\nimport { shareAll } from '@nx\u002Fangular\u002Fmodule-federation';\n\nexport const baseConfig = {\n  shared: {\n    \u002F\u002F ✅ requiredVersion: 'auto' lê do package.json do workspace\n    \u002F\u002F strictVersion: true → falha se versão incompatível\n    '@angular\u002Fcore': {\n      singleton: true,\n      strictVersion: true,\n      requiredVersion: 'auto', \u002F\u002F ← Nx resolve do root package.json\n    },\n    '@angular\u002Frouter': { singleton: true, strictVersion: true, requiredVersion: 'auto' },\n    '@angular\u002Fforms': { singleton: true, strictVersion: true, requiredVersion: 'auto' },\n  }\n};\n",{"type":270,"attrs":285,"content":289},{"id":286,"language":287,"highlighted":288},"code_qxeefz63","bash","\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\"># Ver quais apps precisam ser (re)deployados após mudança em libs\u002Fauth\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">nx\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> affected --target=build --base=main\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">#\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> Output:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">#\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> Affected projects:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">#\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">   shell          ← host sempre afetado quando auth muda\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">#\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">   checkout-mfe   ← usa AuthGuard da libs\u002Fauth\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">#\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">   admin-mfe      ← usa AuthService da libs\u002Fauth\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">#\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> NOT affected:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">#\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">   catalog-mfe    ← não depende de libs\u002Fauth\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">#\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> Quando você ATUALIZA o Angular (major version):\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">nx\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> migrate @angular\u002Fcore@22\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">nx\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> migrate --run-migrations\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">#\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> Aplica migrações em TODOS os apps do workspace de uma vez\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",[290],{"text":291,"type":81},"# Ver quais apps precisam ser (re)deployados após mudança em libs\u002Fauth\nnx affected --target=build --base=main\n\n# Output:\n# Affected projects:\n#   shell          ← host sempre afetado quando auth muda\n#   checkout-mfe   ← usa AuthGuard da libs\u002Fauth\n#   admin-mfe      ← usa AuthService da libs\u002Fauth\n# NOT affected:\n#   catalog-mfe    ← não depende de libs\u002Fauth\n\n# Quando você ATUALIZA o Angular (major version):\nnx migrate @angular\u002Fcore@22\nnx migrate --run-migrations\n# Aplica migrações em TODOS os apps do workspace de uma vez\n",{"type":121,"attrs":293,"content":295},{"id":294},"quote_3tamwkkv",[296],{"type":75,"attrs":297,"content":299},{"id":298},"p_apvf9wzi",[300,304,306,310],{"text":301,"type":81,"marks":302},"⚠️ La regla de Angular en monorepo Nx",[303],{"type":100},{"text":305,"type":81}," Cuando actualizas Angular en un workspace Nx, ",{"text":307,"type":81,"marks":308},"todas las apps del workspace se actualizan juntas",[309],{"type":100},{"text":311,"type":81},". Esto es intencional; la alternativa es el infierno de versiones mixtas. Si dos equipos necesitan versiones diferentes de Angular, necesitan repositorios separados, y ahí pierden las ventajas del monorepo Nx.",{"type":83},{"type":85,"attrs":314,"content":316},{"id":315,"level":88},"h_ueb223he",[317],{"text":318,"type":81},"Solución 02 — CSS leaking",{"type":85,"attrs":320,"content":322},{"id":321,"level":259},"h_yc2nnn3y",[323],{"text":324,"type":81},"Aislamiento de estilos: ViewEncapsulation no es suficiente",{"type":75,"attrs":326,"content":328},{"id":327},"p_ge968kyo",[329],{"text":330,"type":81},"El ViewEncapsulation de Angular aísla estilos de componentes pero no resuelve los estilos globales que cada remote define.",{"type":270,"attrs":332,"content":336},{"id":333,"language":334,"highlighted":335},"code_e4uta8u1","css","\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* ❌ Sem namespace — vaza para o shell e outros remotes *\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">.card\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> { \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">background\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">#1a1a2e\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">; \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">border-radius\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">8\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">px\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\">.btn\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  { \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">background\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">#e94560\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">; \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">color\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">white\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\">.overlay\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> { \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">z-index\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">1000\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">; }  \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F* ← conflita com overlays do shell *\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",[337],{"text":338,"type":81},"\u002F* ❌ Sem namespace — vaza para o shell e outros remotes *\u002F\n.card { background: #1a1a2e; border-radius: 8px; }\n.btn  { background: #e94560; color: white; }\n.overlay { z-index: 1000; }  \u002F* ← conflita com overlays do shell *\u002F\n",{"type":270,"attrs":340,"content":343},{"id":341,"language":334,"highlighted":342},"code_kimisvqc","\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* ✅ Solução 1: Namespace SCSS por remote *\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F* checkout-mfe\u002Fsrc\u002Fstyles.scss *\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">.checkout-mfe\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\">card\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">   { \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">background\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">#1a1a2e\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">; \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">border-radius\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">8\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">px\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\">  .btn\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    { \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">background\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">#e94560\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">; \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">color\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">white\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\">  .overlay\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> { \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">z-index\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">100\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:#6A737D;--shiki-dark:#6A737D\">\u002F* No componente raiz do remote: *\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F* &#x3C;div class=\"checkout-mfe\">&#x3C;router-outlet \u002F>&#x3C;\u002Fdiv> *\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F* ✅ Solução 2: CSS Custom Properties do Design System no shell *\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F* O shell define as variáveis. Os remotes consomem. Nunca definem. *\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">:root\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\">  --ds-color-primary\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">#dd0031\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\">  --ds-color-surface\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">#161b22\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\">  --ds-radius-card\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">8\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">px\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\">  --ds-z-overlay\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">200\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\">  --ds-z-modal\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:   \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">300\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\">  --ds-z-toast\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:   \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">400\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:#6A737D;--shiki-dark:#6A737D\">\u002F* Remotes APENAS consomem variáveis — nunca definem novos z-index absolutos *\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",[344],{"text":345,"type":81},"\u002F* ✅ Solução 1: Namespace SCSS por remote *\u002F\n\u002F* checkout-mfe\u002Fsrc\u002Fstyles.scss *\u002F\n.checkout-mfe {\n  .card   { background: #1a1a2e; border-radius: 8px; }\n  .btn    { background: #e94560; color: white; }\n  .overlay { z-index: 100; }\n}\n\n\u002F* No componente raiz do remote: *\u002F\n\u002F* \u003Cdiv class=\"checkout-mfe\">\u003Crouter-outlet \u002F>\u003C\u002Fdiv> *\u002F\n\n\u002F* ✅ Solução 2: CSS Custom Properties do Design System no shell *\u002F\n\u002F* O shell define as variáveis. Os remotes consomem. Nunca definem. *\u002F\n:root {\n  --ds-color-primary: #dd0031;\n  --ds-color-surface: #161b22;\n  --ds-radius-card: 8px;\n  --ds-z-overlay: 200;\n  --ds-z-modal:   300;\n  --ds-z-toast:   400;\n}\n\n\u002F* Remotes APENAS consomem variáveis — nunca definem novos z-index absolutos *\u002F\n",{"type":121,"attrs":347,"content":349},{"id":348},"quote_ucgrlxvx",[350],{"type":75,"attrs":351,"content":353},{"id":352},"p_e3tpmk2k",[354,358,360,364,366,370],{"text":355,"type":81,"marks":356},"✅ La regla de oro de CSS en MFEs",[357],{"type":100},{"text":359,"type":81}," ",{"text":361,"type":81,"marks":362},"El shell es el único dueño de los estilos globales.",[363],{"type":100},{"text":365,"type":81}," Los remotes consumen CSS Custom Properties definidas por el shell. ",{"text":367,"type":81,"marks":368},"Ningún remote define valores absolutos de z-index",[369],{"type":100},{"text":371,"type":81}," — ese es el bug más difícil de depurar en producción, porque z-index depende del contexto de apilamiento y el shell no controla el contexto del remote.",{"type":83},{"type":85,"attrs":374,"content":376},{"id":375,"level":88},"h_29psv36z",[377],{"text":378,"type":81},"Solución 03 — Estado compartido",{"type":85,"attrs":380,"content":382},{"id":381,"level":259},"h_haz8sg9r",[383],{"text":384,"type":81},"El estado que destruye el deploy independiente",{"type":121,"attrs":386,"content":388},{"id":387},"quote_kzx5hri1",[389],{"type":75,"attrs":390,"content":392},{"id":391},"p_xh34wmdu",[393,397,399,403,405,409],{"text":394,"type":81,"marks":395},"⚠️ El antipatrón más común en MFEs",[396],{"type":100},{"text":398,"type":81}," Colocar el estado del usuario autenticado en un NgRx Store ",{"text":400,"type":81,"marks":401},"compartido vía Module Federation",[402],{"type":100},{"text":404,"type":81}," entre todos los remotes. Parece correcto: \"es estado global, debe estar en el NgRx global\". El problema es que cualquier cambio en el shape de ese estado exige que ",{"text":406,"type":81,"marks":407},"todos los remotes sean actualizados y desplegados al mismo tiempo",[408],{"type":100},{"text":410,"type":81},". El deploy \"independiente\" deja de ser independiente.",{"type":270,"attrs":412,"content":415},{"id":413,"language":58,"highlighted":414},"code_6rkrr1jd","\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 libs\u002Fcore\u002Fsrc\u002Flib\u002Fevent-bus.service.ts\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F ✅ O Event Bus é o contrato entre remotes — não o shape do estado\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\"> { Injectable } \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">from\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '@angular\u002Fcore'\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\"> { Subject, filter, map } \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">from\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> 'rxjs'\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\">export\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> interface\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> MfeEvent\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:#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\">  payload\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> unknown\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>\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\">export\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> type\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> UserAuthenticatedEvent\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> MfeEvent\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> &#x26;\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:#032F62;--shiki-dark:#9ECBFF\"> 'user.authenticated'\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:#24292E;--shiki-dark:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\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>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">    tenantId\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:#6A737D;--shiki-dark:#6A737D\">    \u002F\u002F ✅ Apenas os campos que outros remotes REALMENTE precisam\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:#D73A49;--shiki-dark:#F97583\">export\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> type\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> CartUpdatedEvent\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> MfeEvent\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> &#x26;\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:#032F62;--shiki-dark:#9ECBFF\"> 'cart.updated'\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:#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:#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\"> EventBusService\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:#6F42C1;--shiki-dark:#B392F0\">MfeEvent\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\">  emit\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\"> MfeEvent\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\">.bus$.\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">next\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(event);\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\">  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:#6F42C1;--shiki-dark:#B392F0\"> MfeEvent\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">>(\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:#6F42C1;--shiki-dark:#B392F0\"> T\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">[\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'type'\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\">e\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =>\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> e.type \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">===\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> type),\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\">e\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =>\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> e \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">as\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>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F ✅ No shell — emite após autenticação\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F eventBus.emit({ type: 'user.authenticated', payload: { userId, tenantId }, source: 'shell' });\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F ✅ No checkout-mfe — escuta sem saber nada do shell\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F eventBus.on&#x3C;UserAuthenticatedEvent>('user.authenticated').subscribe(...)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F Quando o shape do usuário muda, você versiona o evento:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F 'user.authenticated.v2' — backward compatible, remotes migram no seu ritmo\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",[416],{"text":417,"type":81},"\u002F\u002F libs\u002Fcore\u002Fsrc\u002Flib\u002Fevent-bus.service.ts\n\u002F\u002F ✅ O Event Bus é o contrato entre remotes — não o shape do estado\nimport { Injectable } from '@angular\u002Fcore';\nimport { Subject, filter, map } from 'rxjs';\n\nexport interface MfeEvent {\n  type: string;\n  payload: unknown;\n  source: string;\n}\n\nexport type UserAuthenticatedEvent = MfeEvent & {\n  type: 'user.authenticated';\n  payload: {\n    userId:   string;\n    tenantId: string;\n    \u002F\u002F ✅ Apenas os campos que outros remotes REALMENTE precisam\n  };\n};\n\nexport type CartUpdatedEvent = MfeEvent & {\n  type: 'cart.updated';\n  payload: { itemCount: number; total: number };\n};\n\n@Injectable({ providedIn: 'root' })\nexport class EventBusService {\n  private bus$ = new Subject\u003CMfeEvent>();\n\n  emit(event: MfeEvent): void {\n    this.bus$.next(event);\n  }\n\n  on\u003CT extends MfeEvent>(type: T['type']) {\n    return this.bus$.pipe(\n      filter(e => e.type === type),\n      map(e => e as T)\n    );\n  }\n}\n\n\u002F\u002F ✅ No shell — emite após autenticação\n\u002F\u002F eventBus.emit({ type: 'user.authenticated', payload: { userId, tenantId }, source: 'shell' });\n\n\u002F\u002F ✅ No checkout-mfe — escuta sem saber nada do shell\n\u002F\u002F eventBus.on\u003CUserAuthenticatedEvent>('user.authenticated').subscribe(...)\n\n\u002F\u002F Quando o shape do usuário muda, você versiona o evento:\n\u002F\u002F 'user.authenticated.v2' — backward compatible, remotes migram no seu ritmo\n",{"type":270,"attrs":419,"content":422},{"id":420,"language":58,"highlighted":421},"code_p54enlzy","\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 ✅ Se você PRECISA de estado compartilhado, compartilhe o mínimo\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\"> const\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> AUTH_CONTEXT\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\"> InjectionToken\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">&#x3C;\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">AuthContext\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">>(\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'AUTH_CONTEXT'\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\">export\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> interface\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> AuthContext\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 Apenas o que é genuinamente necessário para TODOS os remotes\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\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:#D73A49;--shiki-dark:#F97583\"> |\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> null\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\">  tenantId\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:#D73A49;--shiki-dark:#F97583\"> |\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> null\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\">  isAuthenticated\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> boolean\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 ❌ NÃO coloque: permissions, roles, profile, preferences\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>\u003C\u002Fcode>\u003C\u002Fpre>",[423],{"text":424,"type":81},"\u002F\u002F ✅ Se você PRECISA de estado compartilhado, compartilhe o mínimo\nexport const AUTH_CONTEXT = new InjectionToken\u003CAuthContext>('AUTH_CONTEXT');\n\nexport interface AuthContext {\n  \u002F\u002F Apenas o que é genuinamente necessário para TODOS os remotes\n  userId:   string | null;\n  tenantId: string | null;\n  isAuthenticated: boolean;\n  \u002F\u002F ❌ NÃO coloque: permissions, roles, profile, preferences\n}\n",{"type":83},{"type":85,"attrs":427,"content":429},{"id":428,"level":88},"h_3r7uwxwp",[430],{"text":431,"type":81},"Solución 04 — Developer Experience",{"type":85,"attrs":433,"content":435},{"id":434,"level":259},"h_9f55wipn",[436],{"text":437,"type":81},"Desarrollo local sin 4 terminales abiertos",{"type":270,"attrs":439,"content":443},{"id":440,"language":441,"highlighted":442},"code_amhbp483","json","\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 shell\u002Fsrc\u002Fassets\u002Fmodule-federation.manifest.json\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F ✅ Dynamic Module Federation — a URL do remote é resolvida em runtime\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:#005CC5;--shiki-dark:#79B8FF\">  \"checkout\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"http:\u002F\u002Flocalhost:4201\"\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\">  \"catalog\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:  \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"http:\u002F\u002Flocalhost:4202\"\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\">  \"admin\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:    \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"http:\u002F\u002Flocalhost:4203\"\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 shell\u002Fsrc\u002Fassets\u002Fmodule-federation.manifest.staging.json\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:#005CC5;--shiki-dark:#79B8FF\">  \"checkout\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"https:\u002F\u002Fcheckout.staging.example.com\"\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\">  \"catalog\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:  \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"https:\u002F\u002Fcatalog.staging.example.com\"\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\">  \"admin\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:    \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"https:\u002F\u002Fadmin.staging.example.com\"\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>\u003C\u002Fcode>\u003C\u002Fpre>",[444],{"text":445,"type":81},"\u002F\u002F shell\u002Fsrc\u002Fassets\u002Fmodule-federation.manifest.json\n\u002F\u002F ✅ Dynamic Module Federation — a URL do remote é resolvida em runtime\n{\n  \"checkout\": \"http:\u002F\u002Flocalhost:4201\",\n  \"catalog\":  \"http:\u002F\u002Flocalhost:4202\",\n  \"admin\":    \"http:\u002F\u002Flocalhost:4203\"\n}\n\n\u002F\u002F shell\u002Fsrc\u002Fassets\u002Fmodule-federation.manifest.staging.json\n{\n  \"checkout\": \"https:\u002F\u002Fcheckout.staging.example.com\",\n  \"catalog\":  \"https:\u002F\u002Fcatalog.staging.example.com\",\n  \"admin\":    \"https:\u002F\u002Fadmin.staging.example.com\"\n}\n",{"type":270,"attrs":447,"content":450},{"id":448,"language":287,"highlighted":449},"code_8g7861ba","\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\"># ✅ Inicia o shell + checkout em modo live\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\"># catalog e admin são servidos como static (sem live reload)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">nx\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> serve shell --devRemotes=checkout\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">#\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> Inicia o shell + dois remotes em modo live\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">nx\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> serve shell --devRemotes=checkout,catalog\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">#\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> Com Dynamic Module Federation — aponta para staging:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">#\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> O dev desenvolve checkout localmente, catalog e admin vêm do staging\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">cp\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> src\u002Fassets\u002Fmodule-federation.manifest.staging.json \\\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">   src\u002Fassets\u002Fmodule-federation.manifest.json\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",[451],{"text":452,"type":81},"# ✅ Inicia o shell + checkout em modo live\n# catalog e admin são servidos como static (sem live reload)\nnx serve shell --devRemotes=checkout\n\n# Inicia o shell + dois remotes em modo live\nnx serve shell --devRemotes=checkout,catalog\n\n# Com Dynamic Module Federation — aponta para staging:\n# O dev desenvolve checkout localmente, catalog e admin vêm do staging\ncp src\u002Fassets\u002Fmodule-federation.manifest.staging.json \\\n   src\u002Fassets\u002Fmodule-federation.manifest.json\n",{"type":121,"attrs":454,"content":456},{"id":455},"quote_u774z4f7",[457],{"type":75,"attrs":458,"content":460},{"id":459},"p_rydjflja",[461,465,467,471,473,477,479,483],{"text":462,"type":81,"marks":463},"→ El patrón Nx recomendado para DX",[464],{"type":100},{"text":466,"type":81}," Configura un target ",{"text":468,"type":81,"marks":469},"serve-with-staging-remotes",[470],{"type":176},{"text":472,"type":81}," en el ",{"text":474,"type":81,"marks":475},"project.json",[476],{"type":176},{"text":478,"type":81}," del shell. ",{"text":480,"type":81,"marks":481},"El desarrollador inicia una única terminal",[482],{"type":100},{"text":484,"type":81},", el shell carga el remote local que está desarrollando y los otros remotes del staging. Ningún mock, ningún stub; entorno real con un remote vivo.",{"type":83},{"type":85,"attrs":487,"content":489},{"id":488,"level":88},"h_kncvfmpz",[490],{"text":491,"type":81},"Solución 05 — Bundle size",{"type":85,"attrs":493,"content":495},{"id":494,"level":259},"h_jo3hr57y",[496],{"text":497,"type":81},"El intercambio que no compartió nada",{"type":270,"attrs":499,"content":502},{"id":500,"language":58,"highlighted":501},"code_3h3g6ovk","\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 ❌ Shared incompleto — cada remote tem sua própria cópia do Material\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">shared\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\u002Fmaterial'\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:#6A737D;--shiki-dark:#6A737D\">  \u002F\u002F Problema: @angular\u002Fmaterial\u002Fbutton é uma entrada separada\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">  \u002F\u002F → Cada remote vai empacotar sua própria cópia desses módulos\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">  \u002F\u002F → Bundle total: shell(mat\u002Fbutton) + checkout(mat\u002Fbutton) = 3x\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>\u003C\u002Fcode>\u003C\u002Fpre>",[503],{"text":504,"type":81},"\u002F\u002F ❌ Shared incompleto — cada remote tem sua própria cópia do Material\nshared: {\n  '@angular\u002Fmaterial': { singleton: true, strictVersion: true },\n  \u002F\u002F Problema: @angular\u002Fmaterial\u002Fbutton é uma entrada separada\n  \u002F\u002F → Cada remote vai empacotar sua própria cópia desses módulos\n  \u002F\u002F → Bundle total: shell(mat\u002Fbutton) + checkout(mat\u002Fbutton) = 3x\n}\n",{"type":270,"attrs":506,"content":509},{"id":507,"language":58,"highlighted":508},"code_tfpocqet","\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 ✅ shareAll com entradas secundárias — a configuração correta\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\"> { shareAll } \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">from\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '@nx\u002Fangular\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:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F shareAll compartilha AUTOMATICAMENTE todos os pacotes do package.json\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F Incluindo entradas secundárias como @angular\u002Fmaterial\u002Fbutton\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\"> const\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> sharedDeps\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> shareAll\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\">  singleton: \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\">  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\">  requiredVersion: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'auto'\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:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F module-federation.config.ts de cada remote:\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\"> const\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> config\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> ModuleFederationConfig\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\">  name: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'checkout'\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\">  exposes: { \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'.\u002FModule'\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'.\u002Fsrc\u002Fapp\u002Fremote-entry\u002Fentry.module.ts'\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\">  shared: {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">    ...\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">sharedDeps,\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 Resultado com shareAll:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F Bundle antes: shell(300KB) + checkout(280KB) + catalog(275KB) = 855KB\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F Bundle depois: shell(300KB) + checkout(80KB) + catalog(75KB) = 455KB\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F Redução de ~47% no total transferido\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",[510],{"text":511,"type":81},"\u002F\u002F ✅ shareAll com entradas secundárias — a configuração correta\nimport { shareAll } from '@nx\u002Fangular\u002Fmodule-federation';\n\n\u002F\u002F shareAll compartilha AUTOMATICAMENTE todos os pacotes do package.json\n\u002F\u002F Incluindo entradas secundárias como @angular\u002Fmaterial\u002Fbutton\nexport const sharedDeps = shareAll({\n  singleton: true,\n  strictVersion: true,\n  requiredVersion: 'auto',\n});\n\n\u002F\u002F module-federation.config.ts de cada remote:\nexport const config: ModuleFederationConfig = {\n  name: 'checkout',\n  exposes: { '.\u002FModule': '.\u002Fsrc\u002Fapp\u002Fremote-entry\u002Fentry.module.ts' },\n  shared: {\n    ...sharedDeps,\n  },\n};\n\n\u002F\u002F Resultado com shareAll:\n\u002F\u002F Bundle antes: shell(300KB) + checkout(280KB) + catalog(275KB) = 855KB\n\u002F\u002F Bundle depois: shell(300KB) + checkout(80KB) + catalog(75KB) = 455KB\n\u002F\u002F Redução de ~47% no total transferido\n",{"type":121,"attrs":513,"content":515},{"id":514},"quote_c2admssb",[516],{"type":75,"attrs":517,"content":519},{"id":518},"p_zm4xbq54",[520,524,526,530,532,536],{"text":521,"type":81,"marks":522},"✅ Nx bundle analysis integrada",[523],{"type":100},{"text":525,"type":81}," Ejecuta ",{"text":527,"type":81,"marks":528},"nx build checkout --analyze",[529],{"type":176},{"text":531,"type":81}," para abrir el Webpack Bundle Analyzer e identificar qué paquetes se están duplicando entre el shell y los remotes. ",{"text":533,"type":81,"marks":534},"Haz este análisis antes del primer deploy en producción",[535],{"type":100},{"text":537,"type":81}," — es mucho más difícil corregir después de que el caché del CDN se haya propagado.",{"type":83},{"type":85,"attrs":540,"content":542},{"id":541,"level":88},"h_uacsphrn",[543],{"text":544,"type":81},"Cuando los microfrontends no son la respuesta",{"type":546,"attrs":547,"content":549},"table",{"id":548},"tbl_piygdh16",[550,581,611,640,669,698,727],{"type":551,"content":552},"tableRow",[553,563,572],{"type":554,"attrs":555,"content":556},"tableHeader",{"align":9,"colspan":30,"rowspan":30,"colwidth":9},[557],{"type":75,"attrs":558,"content":560},{"id":559},"p_qaufhhjh",[561],{"text":562,"type":81},"Criterio",{"type":554,"attrs":564,"content":565},{"align":9,"colspan":30,"rowspan":30,"colwidth":9},[566],{"type":75,"attrs":567,"content":569},{"id":568},"p_3zodj07o",[570],{"text":571,"type":81},"Microfrontends",{"type":554,"attrs":573,"content":574},{"align":9,"colspan":30,"rowspan":30,"colwidth":9},[575],{"type":75,"attrs":576,"content":578},{"id":577},"p_2i0oz5ei",[579],{"text":580,"type":81},"Monolito modular con Nx",{"type":551,"content":582},[583,593,602],{"type":584,"attrs":585,"content":586},"tableCell",{"align":9,"colspan":30,"rowspan":30,"colwidth":9},[587],{"type":75,"attrs":588,"content":590},{"id":589},"p_3niyoqqy",[591],{"text":592,"type":81},"Tamaño del equipo",{"type":584,"attrs":594,"content":595},{"align":9,"colspan":30,"rowspan":30,"colwidth":9},[596],{"type":75,"attrs":597,"content":599},{"id":598},"p_vlouaufl",[600],{"text":601,"type":81},"✅ 5+ equipos paralelos",{"type":584,"attrs":603,"content":604},{"align":9,"colspan":30,"rowspan":30,"colwidth":9},[605],{"type":75,"attrs":606,"content":608},{"id":607},"p_047zd1hx",[609],{"text":610,"type":81},"✅ 1-3 equipos — el costo de MFE no compensa",{"type":551,"content":612},[613,622,631],{"type":584,"attrs":614,"content":615},{"align":9,"colspan":30,"rowspan":30,"colwidth":9},[616],{"type":75,"attrs":617,"content":619},{"id":618},"p_7wl2sdm3",[620],{"text":621,"type":81},"Cadencia de deploy",{"type":584,"attrs":623,"content":624},{"align":9,"colspan":30,"rowspan":30,"colwidth":9},[625],{"type":75,"attrs":626,"content":628},{"id":627},"p_w50pt1a0",[629],{"text":630,"type":81},"✅ Equipos con cadencias diferentes",{"type":584,"attrs":632,"content":633},{"align":9,"colspan":30,"rowspan":30,"colwidth":9},[634],{"type":75,"attrs":635,"content":637},{"id":636},"p_lqjq2dzx",[638],{"text":639,"type":81},"✅ Misma cadencia — el deploy unificado es más simple",{"type":551,"content":641},[642,651,660],{"type":584,"attrs":643,"content":644},{"align":9,"colspan":30,"rowspan":30,"colwidth":9},[645],{"type":75,"attrs":646,"content":648},{"id":647},"p_nwtnujn7",[649],{"text":650,"type":81},"Dominios de negocio",{"type":584,"attrs":652,"content":653},{"align":9,"colspan":30,"rowspan":30,"colwidth":9},[654],{"type":75,"attrs":655,"content":657},{"id":656},"p_l5r2iyrp",[658],{"text":659,"type":81},"✅ Dominios genuinamente independientes",{"type":584,"attrs":661,"content":662},{"align":9,"colspan":30,"rowspan":30,"colwidth":9},[663],{"type":75,"attrs":664,"content":666},{"id":665},"p_ikpxq0gd",[667],{"text":668,"type":81},"❌ Mucha interdependencia — MFE crea fronteras artificiales",{"type":551,"content":670},[671,680,689],{"type":584,"attrs":672,"content":673},{"align":9,"colspan":30,"rowspan":30,"colwidth":9},[674],{"type":75,"attrs":675,"content":677},{"id":676},"p_r82n7jsq",[678],{"text":679,"type":81},"Bundle inicial",{"type":584,"attrs":681,"content":682},{"align":9,"colspan":30,"rowspan":30,"colwidth":9},[683],{"type":75,"attrs":684,"content":686},{"id":685},"p_lgkbwf9z",[687],{"text":688,"type":81},"❌ Mayor — overhead de Module Federation",{"type":584,"attrs":690,"content":691},{"align":9,"colspan":30,"rowspan":30,"colwidth":9},[692],{"type":75,"attrs":693,"content":695},{"id":694},"p_cnn0qhs7",[696],{"text":697,"type":81},"✅ Menor",{"type":551,"content":699},[700,709,718],{"type":584,"attrs":701,"content":702},{"align":9,"colspan":30,"rowspan":30,"colwidth":9},[703],{"type":75,"attrs":704,"content":706},{"id":705},"p_ba31763f",[707],{"text":708,"type":81},"Complejidad de config",{"type":584,"attrs":710,"content":711},{"align":9,"colspan":30,"rowspan":30,"colwidth":9},[712],{"type":75,"attrs":713,"content":715},{"id":714},"p_91hdyega",[716],{"text":717,"type":81},"❌ Alta — versiones, CSS, estado, DX",{"type":584,"attrs":719,"content":720},{"align":9,"colspan":30,"rowspan":30,"colwidth":9},[721],{"type":75,"attrs":722,"content":724},{"id":723},"p_nx9kdp95",[725],{"text":726,"type":81},"✅ Baja",{"type":551,"content":728},[729,738,747],{"type":584,"attrs":730,"content":731},{"align":9,"colspan":30,"rowspan":30,"colwidth":9},[732],{"type":75,"attrs":733,"content":735},{"id":734},"p_6sp1v492",[736],{"text":737,"type":81},"DX local",{"type":584,"attrs":739,"content":740},{"align":9,"colspan":30,"rowspan":30,"colwidth":9},[741],{"type":75,"attrs":742,"content":744},{"id":743},"p_v35je3u8",[745],{"text":746,"type":81},"⚠️ Degradada sin configuración cuidadosa",{"type":584,"attrs":748,"content":749},{"align":9,"colspan":30,"rowspan":30,"colwidth":9},[750],{"type":75,"attrs":751,"content":753},{"id":752},"p_h58e4h1i",[754,756],{"text":755,"type":81},"✅ Simple — ",{"text":757,"type":81,"marks":758},"ng serve",[759],{"type":176},{"type":121,"attrs":761,"content":763},{"id":762},"quote_om76dzss",[764],{"type":75,"attrs":765,"content":767},{"id":766},"p_7j0ppo4o",[768,772,774,778],{"text":769,"type":81,"marks":770},"→ La recomendación de Nx",[771],{"type":100},{"text":773,"type":81}," La documentación oficial de Nx es directa: ",{"text":775,"type":81,"marks":776},"\"Si quieres optimizar builds y no necesitas deploys independientes, usa nuestra guía de Faster Builds con Module Federation.\"",[777],{"type":100},{"text":779,"type":81}," Puedes tener builds incrementales, caché inteligente y repositorio único sin la complejidad de remotes desplegados independientemente. Esa es la respuesta correcta para la mayoría de los equipos de hasta 30 personas.",{"type":85,"attrs":781,"content":783},{"id":782,"level":259},"h_dhp1xxts",[784],{"text":785,"type":81},"El checklist antes de adoptar microfrontends",{"type":787,"attrs":788,"content":791},"bulletList",{"id":789,"tight":790},"ul_ossnjo8n",true,[792,809,824,839,854,869,885,900,916],{"type":793,"attrs":794,"content":796},"listItem",{"id":795},"li_hxk4sxtu",[797],{"type":75,"attrs":798,"content":800},{"id":799},"p_5u2girs9",[801,803,807],{"text":802,"type":81},"✅ ",{"text":804,"type":81,"marks":805},"5+ equipos",[806],{"type":100},{"text":808,"type":81}," que necesitan desplegar con cadencias genuinamente diferentes",{"type":793,"attrs":810,"content":812},{"id":811},"li_ifi9pvkw",[813],{"type":75,"attrs":814,"content":816},{"id":815},"p_9lrupgzq",[817,818,822],{"text":802,"type":81},{"text":819,"type":81,"marks":820},"Dominios de negocio claros",[821],{"type":100},{"text":823,"type":81}," que no comparten estado más allá de la autenticación",{"type":793,"attrs":825,"content":827},{"id":826},"li_ete3pu6z",[828],{"type":75,"attrs":829,"content":831},{"id":830},"p_papg042s",[832,833,837],{"text":802,"type":81},{"text":834,"type":81,"marks":835},"SLAs independientes",[836],{"type":100},{"text":838,"type":81}," — un fallo en el checkout no debe afectar al catalog",{"type":793,"attrs":840,"content":842},{"id":841},"li_k7xxbgu3",[843],{"type":75,"attrs":844,"content":846},{"id":845},"p_xdt899a8",[847,848,852],{"text":802,"type":81},{"text":849,"type":81,"marks":850},"Design system establecido",[851],{"type":100},{"text":853,"type":81}," vía CSS Custom Properties antes de comenzar",{"type":793,"attrs":855,"content":857},{"id":856},"li_6kcrz6ev",[858],{"type":75,"attrs":859,"content":861},{"id":860},"p_6l1mhckt",[862,863,867],{"text":802,"type":81},{"text":864,"type":81,"marks":865},"Gobernanza de versiones",[866],{"type":100},{"text":868,"type":81}," — política clara para actualizaciones de Angular",{"type":793,"attrs":870,"content":872},{"id":871},"li_twg74o3j",[873],{"type":75,"attrs":874,"content":876},{"id":875},"p_qpeyylvt",[877,879,883],{"text":878,"type":81},"❌ ",{"text":880,"type":81,"marks":881},"Equipo único",[882],{"type":100},{"text":884,"type":81}," que \"va a crecer\" — anticípate con módulos lazy, no con MFE",{"type":793,"attrs":886,"content":888},{"id":887},"li_13rbkc8c",[889],{"type":75,"attrs":890,"content":892},{"id":891},"p_o6x8vmba",[893,894,898],{"text":878,"type":81},{"text":895,"type":81,"marks":896},"Complejidad técnica",[897],{"type":100},{"text":899,"type":81}," como objetivo — MFE es para problemas organizacionales",{"type":793,"attrs":901,"content":903},{"id":902},"li_72aqvg5n",[904],{"type":75,"attrs":905,"content":907},{"id":906},"p_2f1958ol",[908,910,914],{"text":909,"type":81},"⚠️ ",{"text":911,"type":81,"marks":912},"Estado compartido extenso",[913],{"type":100},{"text":915,"type":81}," entre los remotes — rediseña los límites antes",{"type":793,"attrs":917,"content":919},{"id":918},"li_1q4fye3y",[920],{"type":75,"attrs":921,"content":923},{"id":922},"p_i0b9d1jz",[924,925,929],{"text":909,"type":81},{"text":926,"type":81,"marks":927},"SEO crítico",[928],{"type":100},{"text":930,"type":81}," — los MFEs con Module Federation son CSR por defecto",{"type":83},{"type":85,"attrs":933,"content":935},{"id":934,"level":88},"h_06b4zzxy",[936],{"text":937,"type":81},"Setup correcto desde cero",{"type":75,"attrs":939,"content":941},{"id":940},"p_q3f8vkua",[942],{"text":943,"type":81},"Cada paso a continuación mitiga un riesgo real de producción. Saltar uno no genera un error inmediato, genera el problema que depurarás en producción 6 meses después.",{"type":75,"attrs":945,"content":947},{"id":946},"p_8xlhuanz",[948],{"text":949,"type":81,"marks":950},"Paso 1 — Crear el workspace Nx con preset Angular:",[951],{"type":100},{"type":270,"attrs":953,"content":956},{"id":954,"language":287,"highlighted":955},"code_dyavdnlq","\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:#6F42C1;--shiki-dark:#B392F0\">npx\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> create-nx-workspace@latest minha-org --preset=angular-monorepo\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",[957],{"text":958,"type":81},"npx create-nx-workspace@latest minha-org --preset=angular-monorepo\n",{"type":75,"attrs":960,"content":962},{"id":961},"p_2lvtaav7",[963,967,969,973],{"text":964,"type":81,"marks":965},"Riesgo mitigado:",[966],{"type":100},{"text":968,"type":81}," sin el preset correcto, el workspace no configura el ",{"text":970,"type":81,"marks":971},"@nx\u002Fenforce-module-boundaries",[972],{"type":176},{"text":974,"type":81}," automáticamente. Sin esta regla de lint, los remotes importarán unos de otros directamente, creando un acoplamiento que hace imposible el deploy independiente. Solo descubrirás el problema cuando intentes desplegar el checkout sin el catalog y el build falle.",{"type":83},{"type":75,"attrs":977,"content":979},{"id":978},"p_0cme1qau",[980],{"text":981,"type":81,"marks":982},"Paso 2 — Generar el shell con Dynamic Module Federation:",[983],{"type":100},{"type":270,"attrs":985,"content":988},{"id":986,"language":287,"highlighted":987},"code_6ettpzs9","\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:#6F42C1;--shiki-dark:#B392F0\">nx\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> g @nx\u002Fangular:host shell --remotes=checkout,catalog,admin --dynamic=true\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",[989],{"text":990,"type":81},"nx g @nx\u002Fangular:host shell --remotes=checkout,catalog,admin --dynamic=true\n",{"type":75,"attrs":992,"content":994},{"id":993},"p_3wyp9hk4",[995,998,1000,1004],{"text":964,"type":81,"marks":996},[997],{"type":100},{"text":999,"type":81}," sin ",{"text":1001,"type":81,"marks":1002},"--dynamic=true",[1003],{"type":176},{"text":1005,"type":81},", la URL de cada remote queda hardcoded en el bundle del shell en tiempo de build. Cambiar la URL de un remote en producción exige rebuild y redeploy de todo el shell, destruyendo la independencia de deploy. Con el manifest JSON dinámico, cambias la URL en runtime sin tocar el shell.",{"type":83},{"type":75,"attrs":1008,"content":1010},{"id":1009},"p_r1g3pg48",[1011],{"text":1012,"type":81,"marks":1013},"Paso 3 — Crear las libs compartidas antes de cualquier feature:",[1014],{"type":100},{"type":270,"attrs":1016,"content":1019},{"id":1017,"language":287,"highlighted":1018},"code_pbkc32br","\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:#6F42C1;--shiki-dark:#B392F0\">nx\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> g @nx\u002Fangular:lib libs\u002Fui\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">nx\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> g @nx\u002Fangular:lib libs\u002Fauth\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">nx\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> g @nx\u002Fangular:lib libs\u002Fcore\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",[1020],{"text":1021,"type":81},"nx g @nx\u002Fangular:lib libs\u002Fui\nnx g @nx\u002Fangular:lib libs\u002Fauth\nnx g @nx\u002Fangular:lib libs\u002Fcore\n",{"type":75,"attrs":1023,"content":1025},{"id":1024},"p_tawaz93j",[1026,1029],{"text":964,"type":81,"marks":1027},[1028],{"type":100},{"text":1030,"type":81}," crear libs después de que los remotes ya existen significa que cada remote ya tiene su propia versión de componentes y servicios. Unificar después es una refactorización dolorosa a la que los equipos se resisten durante meses. Crear antes fuerza la disciplina de \"código compartido va a libs\" desde el primer commit; el acoplamiento nunca llega a existir.",{"type":83},{"type":75,"attrs":1033,"content":1035},{"id":1034},"p_kh23xu2x",[1036,1040,1044],{"text":1037,"type":81,"marks":1038},"Paso 4 — Configurar la base de shared config en ",[1039],{"type":100},{"text":1041,"type":81,"marks":1042},"libs\u002Fshared-mf-config",[1043],{"type":176},{"text":1045,"type":81,"marks":1046},":",[1047],{"type":100},{"type":270,"attrs":1049,"content":1052},{"id":1050,"language":58,"highlighted":1051},"code_luolt9av","\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 shareAll({ singleton: true, strictVersion: true, requiredVersion: 'auto' })\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",[1053],{"text":1054,"type":81},"\u002F\u002F shareAll({ singleton: true, strictVersion: true, requiredVersion: 'auto' })\n",{"type":75,"attrs":1056,"content":1058},{"id":1057},"p_d8b7rd7b",[1059,1062,1064,1067],{"text":964,"type":81,"marks":1060},[1061],{"type":100},{"text":1063,"type":81}," sin una config base centralizada, cada remote define su propio ",{"text":232,"type":81,"marks":1065},[1066],{"type":176},{"text":1068,"type":81}," — e invariablemente alguien olvida incluir las entradas secundarias de Angular Material o del CDK. El resultado es el Problema 05: bundle 3 veces mayor. Con la config base en el monorepo, un único PR corrige todos los remotes al mismo tiempo.",{"type":83},{"type":75,"attrs":1071,"content":1073},{"id":1072},"p_y4dnjaka",[1074,1078,1080,1084,1086,1090],{"text":1075,"type":81,"marks":1076},"Paso 5 — Establecer el Design System en el shell antes del primer remote:",[1077],{"type":100},{"text":1079,"type":81}," Define todas las CSS Custom Properties en ",{"text":1081,"type":81,"marks":1082},"shell\u002Fsrc\u002Fstyles.scss",[1083],{"type":176},{"text":1085,"type":81}," y documenta la convención de namespace (ej: ",{"text":1087,"type":81,"marks":1088},".checkout-mfe { ... }",[1089],{"type":176},{"text":1091,"type":81},").",{"type":75,"attrs":1093,"content":1095},{"id":1094},"p_rztrnxf7",[1096,1099],{"text":964,"type":81,"marks":1097},[1098],{"type":100},{"text":1100,"type":81}," sin tokens CSS centralizados, cada remote define sus propios valores de color, espaciado y z-index. En 3 meses tienes 4 sistemas de diseño divergentes y CSS leaking no determinista (Problema 02). Refactorizar esto después significa convencer a 4 equipos de dejar de entregar features para alinear variables CSS — conversación que nunca sucede.",{"type":83},{"type":75,"attrs":1103,"content":1105},{"id":1104},"p_g47l5l6j",[1106,1110,1111,1115,1117,1121],{"text":1107,"type":81,"marks":1108},"Paso 6 — Implementar el EventBusService antes del primer flujo cross-remote:",[1109],{"type":100},{"text":359,"type":81},{"text":1112,"type":81,"marks":1113},"libs\u002Fcore\u002Fsrc\u002Flib\u002Fevent-bus.service.ts",[1114],{"type":176},{"text":1116,"type":81}," con tipos de evento en ",{"text":1118,"type":81,"marks":1119},"libs\u002Fcore\u002Fsrc\u002Flib\u002Fevents.ts",[1120],{"type":176},{"text":1122,"type":81},".",{"type":75,"attrs":1124,"content":1126},{"id":1125},"p_rvqn47mq",[1127,1130],{"text":964,"type":81,"marks":1128},[1129],{"type":100},{"text":1131,"type":81}," sin un contrato de comunicación establecido, el primer desarrollador que necesite pasar datos entre remotes pondrá estado en el NgRx global, creando el Problema 03. El EventBus obliga al equipo a pensar en contratos versionados antes de crear la dependencia de estado. Es mucho más fácil establecer el patrón correcto antes del primer flujo que eliminar estado global después de que 3 equipos dependan de él.",{"type":83},{"type":270,"attrs":1134,"content":1137},{"id":1135,"language":287,"highlighted":1136},"code_ldd5w032","\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\"># Estrutura de workspace que aguenta 2 anos de produção\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">minha-org\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">├──\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> apps\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">│\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">   ├── shell\u002F              # Host — roteamento e layout global\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">│\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">   ├── checkout-mfe\u002F       # Remote — domínio de pagamento\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">│\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">   ├── catalog-mfe\u002F        # Remote — domínio de catálogo\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">│\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">   └── admin-mfe\u002F          # Remote — domínio administrativo\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">├──\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> libs\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">│\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">   ├── ui\u002F                 # Design System — components, tokens CSS\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">│\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">   ├── auth\u002F               # AuthGuard, AuthContext, EventBus types\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">│\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">   ├── core\u002F               # EventBus, interceptors, error handler\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">│\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">   ├── shared-mf-config\u002F   # Base config de Module Federation\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">│\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">   └── data-access\u002F        # APIs compartilhadas (opcional)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">├──\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> module-federation.manifest.json          # dev\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">├──\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> module-federation.manifest.staging.json  # staging\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">├──\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> module-federation.manifest.prod.json     # produção\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">└──\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> nx.json\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",[1138],{"text":1139,"type":81},"# Estrutura de workspace que aguenta 2 anos de produção\nminha-org\u002F\n├── apps\u002F\n│   ├── shell\u002F              # Host — roteamento e layout global\n│   ├── checkout-mfe\u002F       # Remote — domínio de pagamento\n│   ├── catalog-mfe\u002F        # Remote — domínio de catálogo\n│   └── admin-mfe\u002F          # Remote — domínio administrativo\n├── libs\u002F\n│   ├── ui\u002F                 # Design System — components, tokens CSS\n│   ├── auth\u002F               # AuthGuard, AuthContext, EventBus types\n│   ├── core\u002F               # EventBus, interceptors, error handler\n│   ├── shared-mf-config\u002F   # Base config de Module Federation\n│   └── data-access\u002F        # APIs compartilhadas (opcional)\n├── module-federation.manifest.json          # dev\n├── module-federation.manifest.staging.json  # staging\n├── module-federation.manifest.prod.json     # produção\n└── nx.json\n",{"type":83},{"type":85,"attrs":1142,"content":1144},{"id":1143,"level":88},"h_36ap224p",[1145],{"text":1146,"type":81},"Lo que realmente importa",{"type":75,"attrs":1148,"content":1150},{"id":1149},"p_5svsyvbu",[1151,1153],{"text":1152,"type":81},"El Module Federation resuelve problemas técnicos de carga federada. Nx resuelve problemas técnicos de build y dependencia. Ninguno de los dos resuelve el problema real: ",{"text":1154,"type":81,"marks":1155},"los microfrontends son una solución para la Conway's Law, no para el rendimiento de build.",[1156],{"type":100},{"type":1158,"attrs":1159,"content":1163},"callout",{"id":1160,"type":1161,"title":1162},"call_shbxdqi4","note","Entiende el papel del Module Federation y de Nx",[1164,1170,1176],{"type":75,"attrs":1165,"content":1167},{"id":1166},"p_wqclpea6",[1168],{"text":1169,"type":81},"Module Federation se enfoca en la carga federada, mientras que Nx gestiona build y dependencias. Ninguna herramienta resuelve la complejidad intrínseca de los microfrontends.",{"type":75,"attrs":1171,"content":1173},{"id":1172},"p_9l4ps16e",[1174],{"text":1175,"type":81},"Los microfrontends son eficaces para equipos que necesitan trabajar de forma independiente, siempre que los dominios de negocio estén bien definidos.",{"type":75,"attrs":1177,"content":1179},{"id":1178},"p_h0t1sn6w",[1180],{"text":1181,"type":81},"Sin esa claridad, el proyecto sufre con la complejidad distribuida y el acoplamiento típico de los monolitos, perjudicando el resultado final.",{"type":75,"attrs":1183,"content":1185},{"id":1184},"p_9fcnorso",[1186],{"text":1187,"type":81},"Si tu problema es que dos equipos no pueden trabajar en el mismo código sin pisarse, los microfrontends pueden ayudar, pero solo si los dominios de negocio tienen fronteras lo suficientemente claras para que los remotes sean genuinamente independientes.",{"type":75,"attrs":1189,"content":1191},{"id":1190},"p_alu9taji",[1192],{"text":1193,"type":81},"La mayoría de los proyectos que adoptan microfrontends sin esa claridad de dominio terminan con lo peor de ambos mundos: la complejidad de la arquitectura distribuida con el acoplamiento del monolito.",{"type":121,"attrs":1195,"content":1197},{"id":1196},"quote_w93dlfca",[1198],{"type":75,"attrs":1199,"content":1201},{"id":1200},"p_x1smvs47",[1202,1206,1207,1211],{"text":1203,"type":81,"marks":1204},"La política en una frase",[1205],{"type":100},{"text":359,"type":81},{"text":1208,"type":81,"marks":1209},"Los microfrontends son para equipos, no para código.",[1210],{"type":100},{"text":1212,"type":81}," Si el driver es \"necesitamos que equipos diferentes desplieguen con cadencias diferentes en dominios de negocio claros\", usa MFE. Si el driver es \"nuestra aplicación se volvió grande\", usa módulos lazy de Angular con Nx incremental builds. La segunda opción resuelve el 80% de los problemas con el 20% de la complejidad.",{"type":75,"attrs":1214},{"id":1215},"p_vgu1iuga",{"type":75,"attrs":1217,"content":1219},{"id":1218},"p_r2pb4ptj",[1220],{"text":1221,"type":81,"marks":1222},"La independencia que los microfrontends prometen cuesta más de lo que el tutorial muestra. Solo vale la pena pagarlo cuando sabes exactamente qué estás comprando.",[1223],{"type":100},{"type":83},{"type":85,"attrs":1226,"content":1228},{"id":1227,"level":88},"h_xpj2jrgc",[1229],{"text":1230,"type":81},"Fuentes",{"type":787,"attrs":1232,"content":1234},{"id":1233,"tight":790},"ul_ebfhb9re",[1235,1249,1274,1288,1309,1326],{"type":793,"attrs":1236,"content":1238},{"id":1237},"li_tou1g94b",[1239],{"type":75,"attrs":1240,"content":1242},{"id":1241},"p_dsc5i1i1",[1243,1247],{"text":1244,"type":81,"marks":1245},"nx.dev\u002Fdocs\u002Ftechnologies\u002Fmodule-federation",[1246],{"type":100},{"text":1248,"type":81}," — Arquitectura oficial de MFE con Nx: cuándo usar, version mismatch, deploys afectados, estrategia de shared libs.",{"type":793,"attrs":1250,"content":1252},{"id":1251},"li_4b6pv4ry",[1253],{"type":75,"attrs":1254,"content":1256},{"id":1255},"p_qlornqzv",[1257,1268,1272],{"text":1258,"type":81,"marks":1259},"blog.angular.dev",[1260,1267],{"type":1261,"attrs":1262},"link",{"rel":1263,"href":1264,"class":1265,"title":9,"target":1266},"noopener noreferrer","http:\u002F\u002Fblog.angular.dev","editor-link","_blank",{"type":100},{"text":1269,"type":81,"marks":1270}," — Manfred Steyer (feb\u002F2025)",[1271],{"type":100},{"text":1273,"type":81}," — \"Micro Frontends with Angular and Native Federation\" — Module Federation vs Native Federation, singleton sharing, strictVersion, ESM + import maps.",{"type":793,"attrs":1275,"content":1277},{"id":1276},"li_d0jicak3",[1278],{"type":75,"attrs":1279,"content":1281},{"id":1280},"p_3aadqt6x",[1282,1286],{"text":1283,"type":81,"marks":1284},"DEV Community — Vitalii Petrenko (may\u002F2025)",[1285],{"type":100},{"text":1287,"type":81}," — \"Microfrontends in 2025: A Reality Check from the Trenches\" — CSS isolation, state management cross-MFE, version governance.",{"type":793,"attrs":1289,"content":1291},{"id":1290},"li_ui152w7z",[1292],{"type":75,"attrs":1293,"content":1295},{"id":1294},"p_wqv735v4",[1296,1303,1307],{"text":1297,"type":81,"marks":1298},"infinum.com",[1299,1302],{"type":1261,"attrs":1300},{"rel":1263,"href":1301,"class":1265,"title":9,"target":1266},"http:\u002F\u002Finfinum.com",{"type":100},{"text":1304,"type":81,"marks":1305}," (dic\u002F2025)",[1306],{"type":100},{"text":1308,"type":81}," — \"Implementing Micro Frontends — What to Look Out For\" — shared packages, actualización de Angular en monorepo.",{"type":793,"attrs":1310,"content":1312},{"id":1311},"li_b78thtya",[1313],{"type":75,"attrs":1314,"content":1316},{"id":1315},"p_vatwkxhy",[1317,1324],{"text":1318,"type":81,"marks":1319},"angulararchitects.io",[1320,1323],{"type":1261,"attrs":1321},{"rel":1263,"href":1322,"class":1265,"title":9,"target":1266},"http:\u002F\u002Fangulararchitects.io",{"type":100},{"text":1325,"type":81}," — \"Multi-Framework and -Version Micro Frontends with Module Federation\" — requiredVersion strategies, bootstrap asíncrono.",{"type":793,"attrs":1327,"content":1329},{"id":1328},"li_jdfw2aa9",[1330],{"type":75,"attrs":1331,"content":1333},{"id":1332},"p_gun7pnwc",[1334,1341,1345],{"text":1335,"type":81,"marks":1336},"javascript-conference.com",[1337,1340],{"type":1261,"attrs":1338},{"rel":1263,"href":1339,"class":1265,"title":9,"target":1266},"http:\u002F\u002Fjavascript-conference.com",{"type":100},{"text":1342,"type":81,"marks":1343}," (jul\u002F2024)",[1344],{"type":100},{"text":1346,"type":81}," — \"Microfrontends in the Monorepo\" — nx affected:apps para deploy selectivo, enforce-module-boundaries.",{"type":75,"attrs":1348},{"id":1349},"p_xchkbeqj","Angular Microfrontends con Nx: 5 problemas reales y soluciones","Version mismatch, CSS filtrado entre remotes, estado compartido que arruina el deploy independiente, DX rota y bundle 3x mayor que el monolito.","2026-08-24T14:53:53.315534+00:00",[1354,1368,1385,1409],{"id":1355,"slug":1356,"title":1357,"excerpt":1358,"image":1359,"featured":43,"groupId":1360,"publishedAt":1361,"readingTime":10,"views":1362,"author":1363,"category":1364,"tags":1365},"560449af-97ed-4bd1-b5d8-78d8f0b5361d","angular-22-reemplace-controlvalueaccessor-con-signal-forms","Angular 22: Reemplace ControlValueAccessor con Signal Forms","Descubre cómo Signal Forms en Angular 22 optimiza el desarrollo de formularios, permitiendo crear controles personalizados con menos código.","https:\u002F\u002Fmfgiomkkbihnlpfdxwrt.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fblog-assets\u002Fmedia\u002Ffeatured\u002F1783824967158-featured-pxdvca.webp","63d1d8ce-b076-4932-955c-91714cb80417","2026-07-17T03:35:30.376651+00:00",0,{"name":48,"avatar":9},{"slug":13,"name":14,"color":15},[1366,1367],{"slug":52,"name":53},{"slug":58,"name":59},{"id":1369,"slug":1370,"title":1371,"excerpt":1372,"image":1373,"featured":43,"groupId":1374,"publishedAt":1375,"readingTime":1376,"views":1362,"author":1377,"category":1378,"tags":1379},"32bcf994-e841-4972-93bd-0ac306ea27ab","deja-de-arriesgar-tu-frontend-la-arquitectura-definitiva-de-angular-22","Deja de arriesgar tu frontend: la arquitectura definitiva de Angular 22","Angular 22 ya está aquí. Descubre cómo los últimos cambios arquitectónicos y las primitivas de reactividad nativa lo convierten en la opción ideal.","https:\u002F\u002Fmfgiomkkbihnlpfdxwrt.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fblog-assets\u002Fmedia\u002Ffeatured\u002F1783664697703-featured-bp1wut.webp","9baf202d-f92f-4667-a3a3-8090369c1c0b","2026-07-11T00:43:41.458059+00:00",18,{"name":48,"avatar":9},{"slug":13,"name":14,"color":15},[1380,1381,1382],{"slug":52,"name":53},{"slug":55,"name":56},{"slug":1383,"name":1384},"nextjs","Next.js",{"id":1386,"slug":1387,"title":1388,"excerpt":1389,"image":1390,"featured":43,"groupId":1391,"publishedAt":1392,"readingTime":1393,"views":1362,"author":1394,"category":1395,"tags":1396},"5bd6a109-60a4-4bbe-981f-191a242146ad","ingenieria-de-la-imagen-el-pipeline-de-produccion-profesional","Ingeniería de la Imagen: el pipeline de producción profesional","Entre el prompt solitario y el pipeline de cinco etapas, la imagen deja de ser una alucinación para convertirse en un producto con control y garantía.","https:\u002F\u002Fmfgiomkkbihnlpfdxwrt.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fblog-assets\u002Fmedia\u002Ffeatured\u002F1781225763131-featured-mg5hov.webp","a242fb24-57d4-46ae-a868-4cf79464409c","2026-06-18T08:03:31.638506+00:00",10,{"name":48,"avatar":9},{"slug":13,"name":14,"color":15},[1397,1400,1403,1406],{"slug":1398,"name":1399},"ai","AI",{"slug":1401,"name":1402},"developer-tools","Developer Tools",{"slug":1404,"name":1405},"llm","LLM",{"slug":1407,"name":1408},"performance","Performance",{"id":1410,"slug":1411,"title":1412,"excerpt":1413,"image":1414,"featured":43,"groupId":1415,"publishedAt":1416,"readingTime":1393,"views":1417,"author":1418,"category":1419,"tags":1420},"cc3e72bb-b3ba-4010-ac52-2ebe086cac09","runtime-el-concepto-que-nadie-te-explico-bien-y-que-lo-cambia-todo-cuando-lo-entiendes","Runtime: El Concepto Que Nadie Te Explicó Bien (Y Que Lo Cambia Todo Cuando Lo Entiendes)","Runtime significa tanto el momento de ejecución como el entorno que ejecuta el código. Entiende esta dualidad, aprende a diferenciar errores de compile time de runtime y ve cómo Node, Deno y Bun aplican este concepto de formas distintas.","https:\u002F\u002Fmfgiomkkbihnlpfdxwrt.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fblog-assets\u002Fmedia\u002Ffeatured\u002F1774464638320-featured-ijck77.jpg","6db59740-4e97-4af7-9572-90cab25f01f8","2026-03-26T03:40:43.344+00:00",56,{"name":48,"avatar":9},{"slug":13,"name":14,"color":15},[1421,1424,1427,1428],{"slug":1422,"name":1423},"runtime","Runtime",{"slug":1425,"name":1426},"nodejs","Node.js",{"slug":58,"name":59},{"slug":55,"name":56},{"es":39,"pt":1430,"en":1431},"microfrontends-com-angular-e-nx-o-que-ninguem-conta","microfrontends-with-angular-and-nx-what-nobody-tells-you"]