Angular使用webpack Module Federation导入微应用出现DOM重复渲染问题
问题根因
该异常是Angular模块联邦场景下共享依赖实例重复 + 变更检测上下文不一致导致的,和你配置的共享依赖规则错误直接相关,可通过以下步骤修复:
修复方案
1. 移除远程应用共享依赖的eager: true配置
当前远程应用的webpack配置中,所有Angular核心依赖都加了eager: true配置,该配置会强制将对应依赖打包到远程的remoteEntry.js中,哪怕宿主已存在相同版本的依赖也会重复加载,最终出现两个@angular/core、@angular/common实例,*ngIf等内置指令所属的实例和组件运行实例不匹配,就会出现变量更新但视图不刷新、条件渲染失效、节点重复渲染的问题。eager配置仅需在宿主侧按需添加,远程应用不需要该配置,直接删除远程webpack配置中四个Angular共享依赖的eager: true参数即可。
2. 补全所有用到的Angular公共依赖共享配置
当前仅共享了@angular/core、@angular/common、@angular/router、@angular/common/http四个包,如果你用到了表单、动画等能力,需要将对应依赖也同步添加到宿主和远程的共享配置中,统一设置为单例模式:
// 宿主和远程的shared配置中都要加 "@angular/forms": { singleton: true, strictVersion: true, requiredVersion: 'auto' }, "@angular/animations": { singleton: true, strictVersion: true, requiredVersion: 'auto' }
3. 对齐宿主和远程的Angular版本
因为配置了strictVersion: true,如果两边Angular相关依赖的版本号(含小版本号)不一致,会直接导致共享失败,加载双份实例,需确保两边package.json中所有Angular相关依赖的版本完全匹配。
4. (可选)手动指定变更检测上下文
如果修改配置后仍有问题,可在远程组件中注入NgZone,手动将变量更新逻辑包裹在Zone上下文内,强制触发正确的变更检测:
// 组件ts代码 import { Component, NgZone } from '@angular/core'; @Component({ // 组件元配置 }) export class TestComponent { hide = true; constructor(private ngZone: NgZone) {} toggleHide() { this.ngZone.run(() => { this.hide = !this.hide; }) } }
<!-- 组件HTML代码 --> <button (click)="toggleHide()">test</button> <p>hide: {{hide}}</p> <div *ngIf="hide"> <p>This is a test</p> </div>
内容的提问来源于stack exchange,提问作者Nulk
相关产品推荐
相关产品推荐

