I'm implementing module federation in my Angular project, below is my Microfrontend's webpack.config.js
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const mf = require("@angular-architects/module-federation/webpack");
const path = require("path");
const share = mf.share;
const sharedMappings = new mf.SharedMappings();
sharedMappings.register(path.join(__dirname, "tsconfig.json"), [
/* mapped paths to share */
]);
module.exports = {
output: {
uniqueName: "mfe1",
publicPath: "auto",
},
optimization: {
runtimeChunk: false,
},
resolve: {
alias: {
...sharedMappings.getAliases(),
},
},
plugins: [
new ModuleFederationPlugin({
// For remotes (please adjust)
name: "mfe",
filename: "remoteEntry.js",
exposes: {
"./Module": "./src/app/microfrontend/microfrontend.module.ts",
"./TestComponent": "./src/app/microfrontend/test/test.component.ts",
},
shared: share({
"@angular/core": { singleton: true, strictVersion: false, requiredVersion: "auto" },
"@angular/common": { singleton: true, strictVersion: false, requiredVersion: "auto"},
"@angular/common/http": { singleton: true, strictVersion: false, requiredVersion: auto" },
"@angular/router": { singleton: true, strictVersion: false, requiredVersion: "auto" },
...sharedMappings.getDescriptors(),
}),
}),
sharedMappings.getPlugin(),
],
};
In shell, I have setup routing to load mfe on path /remote which is i could navigate on shell without any issue. Below is my route path
{
path: 'remote',
loadChildren: () =>
loadRemoteModule({
remoteEntry: 'http://localhost:3000/remoteEntry.js',
remoteName: 'mfe',
exposedModule: './Module',
}).then((m) => {
return m.MicrofrontendModule;
}),
}
I'm trying to load TestComponent from MFE into shell using below directive and service
mfe-load-directive.ts
import { Directive, Input, OnChanges, ViewContainerRef } from '@angular/core';
import { MFELoaderService } from './mfe-loader.service';
@Directive({
selector: '[appMicrofrontendLoader]'
})
export class MFELoaderDirective implements OnChanges {
@Input() appMFELoader!: any;
constructor(
private viewContainerRef: ViewContainerRef,
private loaderService: MFELoaderService
) { }
ngOnChanges(): void {
this.loaderService.loadMFE(this.viewContainerRef);
}
}
mfe-loader.service.ts
import { loadRemoteModule } from "@angular-architects/module-federation";
import { ComponentRef, Injectable, ViewContainerRef } from "@angular/core";
@Injectable({
providedIn: 'root'
})
export class MFELoaderService {
public loadMFE(viewContainerRef: ViewContainerRef) {
let data = {
"remoteUrl" : "http://localhost:3000",
"path": "/remoteEntry.js",
"name": "mfe",
"component": "TestComponent",
};
const url = data.remoteUrl;
loadRemoteModule({
type: 'module',
remoteEntry: `${url}${data.path}`,
exposedModule: `./${data.component}`
}).then(m => {
viewContainerRef.clear();
const component: ComponentRef<any> = viewContainerRef.createComponent(m[data.component]);
});
}
}
Template
<div [appMFELoader]="'doNothing'"></div>
When i try to access MFE on route http://localhost:4200/remote, I'm able to load the MFE, but if it try to load TestComponent by using viewContainerRef.createComponent() method getting below errors
Error: Uncaught (in promise): TypeError: container.init is not a function Error: Uncaught (in promise): TypeError: container.get is not a function
Can I get some help to resolve it?