I want to use angular app inside react app using module federation. I found a way to use angular's app.component in React. But I can't use other components. I am sharing the codes below.
Angular webpack config
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"), [
]);
module.exports = {
output: {
uniqueName: "mfeRemote",
publicPath: "auto",
scriptType: "text/javascript",
},
optimization: {
runtimeChunk: false,
},
resolve: {
alias: {
...sharedMappings.getAliases(),
},
},
experiments: {
outputModule: true,
},
plugins: [
new ModuleFederationPlugin({
name: "mfeRemote",
filename: "remoteEntry.js",
exposes: {
"./AppModule": "./src/loadApp.ts",
"./DashComp": "./src/app/external/dashboard/dashboard.component.ts",
},
shared: share({
"@angular/core": {
singleton: true,
strictVersion: true,
requiredVersion: "auto",
},
"@angular/common": {
singleton: true,
strictVersion: true,
requiredVersion: "auto",
},
"@angular/common/http": {
singleton: true,
strictVersion: true,
requiredVersion: "auto",
},
"@angular/router": {
singleton: true,
strictVersion: true,
requiredVersion: "auto",
},
...sharedMappings.getDescriptors(),
}),
}),
sharedMappings.getPlugin(),
],
};
loadApp.ts
import 'zone.js';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
const mount = () => {
platformBrowserDynamic()
.bootstrapModule(AppModule)
.catch((err) => console.error(err));
};
export { mount };
React Craco config
const ModuleFederationPlugin = require("webpack").container.ModuleFederationPlugin;
const deps = require("./package.json").dependencies;
module.exports = {
plugins: [
{
plugin: {
overrideCracoConfig: ({ cracoConfig, pluginOptions, context: { env, paths } }) => {
return cracoConfig;
},
overrideWebpackConfig: ({ webpackConfig, cracoConfig, pluginOptions, context: { env, paths } }) => {
webpackConfig.plugins = [
...webpackConfig.plugins,
new ModuleFederationPlugin({
name: "app",
remotes: {
appModule: "mfeRemote@http://localhost:3002/remoteEntry.js",
},
shared: {
...deps,
"react-dom": {
singleton: true,
eager: true,
},
react: {
singleton: true,
eager: true,
},
},
}),
];
return webpackConfig;
},
overrideDevServerConfig: ({
devServerConfig,
cracoConfig,
pluginOptions,
context: { env, paths, proxy, allowedHost },
}) => {
return devServerConfig;
},
overrideJestConfig: ({ jestConfig, cracoConfig, pluginOptions, context: { env, paths, resolve, rootDir } }) => {
return jestConfig;
},
},
},
],
};
React using App-Component (is Work)
import React, { useEffect, useRef } from "react";
import { mount } from "appModule/AppModule";
const RemoteAppModule = () => {
const ref = useRef(null);
useEffect(() => {
mount();
}, []);
return (
<div className="remote-module">
<app-root></app-root>
</div>
);
};
export default RemoteAppModule;
React using Other Comp (not Work)
import React from "react";
let DashComp = React.lazy(() =>
import("appModule/DashComp").then((module) => {
// this row for -> class component without new
let ExtModule = new module.DashboardComponent();
return { default: ExtModule };
})
);
const RemoteExtModule = () => {
return (
<div>
<React.Suspense fallback="...loading">
<DashComp />
</React.Suspense>
</div>
);
};
export default RemoteExtModule;
Error
------------------UPDATE ------------------------------------------
i solved my problem different way. I used multiple bootstrap module .
check my repo :