1

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

enter image description here

------------------UPDATE ------------------------------------------

i solved my problem different way. I used multiple bootstrap module .

check my repo :

https://github.com/scerci/mfe-angular-react

Scerci
  • 11
  • 2

0 Answers0