我拿起了https://www.angulararchitects.io/en/aktuelles/multi-framework-and-version-micro-frontends-with-module-federation-the-good-the-bad-the-ugly的 git 示例/进一步引用为Ex。1 和https://www.angulararchitects.io/en/aktuelles/dynamic-module-federation-with-angular/进一步引用为 Ex。2.
前任。1 中有多个角度项目。为了简化起见,只需使用 shell 和 mfe1(微前端 1)。该示例对每个项目使用package.json
and angular.json
,我想使用它是因为在现实世界中,我们可能有很多微前端,并且不想一次更新所有依赖项或管理所有依赖项。在这个例子中,罪魁祸首是它使用了 aWrapperComponent
和 a registry.ts
。当一个路由被激活时,它会通过这个函数延迟加载:
ngAfterContentInit(): void {
const elementName = this.route.snapshot.data['elementName'];
const importName = this.route.snapshot.data['importName'];
const importFn = registry[importName];
importFn()
.then(_ => console.debug(`element ${elementName} loaded!`))
.catch(err => console.error(`error loading ${elementName}:`, err));
const element = document.createElement(elementName);
this.vc.nativeElement.appendChild(element);
}
registry
包含一个映射,如
export const registry = {
mfe1: () => import('mfe1/web-components')
};
AFAIK 发生了一些“webpack 魔术”来进行导入,并mfe1
通过webpack.config.js
. 这意味着我需要在编译时知道微前端的数量和名称。
前任。2 使用动态方法,通过使用LookupService
export class LookupService {
lookup(): Promise<Microfrontend[]> {
return Promise.resolve([
{
// For Loading
remoteEntry: 'http://localhost:3000/remoteEntry.js',
remoteName: 'mfe1',
exposedModule: './Module',
// For Routing
displayName: 'Flights',
routePath: 'flights',
ngModuleName: 'FlightsModule'
}
] as Microfrontend[]);
}
}
以及构建路线的功能
export function buildRoutes(options: Microfrontend[]): Routes {
const lazyRoutes: Routes = options.map(o => ({
path: o.routePath,
loadChildren: () => loadRemoteModule(o).then(m => m[o.ngModuleName])
}));
return [...APP_ROUTES, ...lazyRoutes];
}
现在,我想结合这两种方法。所以,我复制了 Ex 的方法。2 进入前。1,现在正在努力解决以下问题。
当简单地公开AppModule
ofmfe1
并动态加载它时,我有多个RouterModule.forRoot()
调用,这是无法避免的,因为mfe1
并且shell
也应该独立工作。这会导致错误。所以,我只是做了一个“虚拟” AppModule
,调用RouterModule.forRoot()
并有一条指向另一个模块的路径,该模块仅使用RouterModule.forChild()
(FlightsModule
在示例中称为)。这个另一个FlightsModule
是动态加载的shell
,因此不再多次调用RouterModule.forRoot()
. 这是必要的还是有其他选择?
因为我只能加载 的一个“子模块” mfe1
,所以我需要转移几个常用文件的内容。mfe1/src/styles.css
对于全局样式,需要将其移动到始终由路由激活的组件,encapsulation: ViewEncapsulation.None
以使其全局可访问,例如在ngx-toastr
需要使用时。微前端不能使用中的styles
选项,因为它在加载到. 通常导入和声明的所有内容都需要转移到子模块。等等...angular.json
shell
AppModule
最后,我认为这种方法绝对不是最好的,但我尝试了很多不同的东西,除了这个,没有一个是有效的。