0

I am trying to build a microfrontends system using webpack's ModuleFederationPlugin.

In the current setup, I have three apps:

1 Angular Host
1 Angular Remote
1 React Remote

The Host works fine and renders the Angular remote fine at /ngMFE.

My issue is the react app does not show on the page, even though
A) I can see the <react-element></react-element> being created in the markup, but is empty
B) In the browser's source tab I can see the remoteEntry.js and other files of the react app being downloaded when navigating to /reactMFE.
C) The app runs normally if launched on its own server.

I am using the @angular-architects/module-federation-tools package.

The host app's routing is setup as follows:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import {HomeComponent} from './core/home/home.component';
import {WebComponentWrapper, WebComponentWrapperOptions} from '@angular-architects/module-federation-tools';

const routes: Routes = [
  {
    path: '',
    component: HomeComponent,
    pathMatch: 'full'
  },
  {
    path: 'ngMFE',
    loadChildren: () => import('mf1/Module').then(m => m.HeroesModule)
  },
  {
    path: 'reactMFE',
    component: WebComponentWrapper,
    data: {
      type: 'script',
      remoteEntry: 'http://localhost:3000/remoteEntry.js',
      remoteName: 'mf2',
      exposedModule: './AppModule',
      elementName: 'react-element',
    } as WebComponentWrapperOptions,
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

The webpack.config file for the react app is the following:

const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const { ModuleFederationPlugin } = require('webpack').container;
const deps = require('./package.json').dependencies;

module.exports = (env, argv) => {
    const mode = 'development';
    console.log({ mode });
    return {
        performance: {
            hints: false
        },
        entry: `./src/index.ts`,
        output: {
            path: path.resolve(__dirname, 'dist'),

            /*
              Take care to make sure this is unique!
              If you are serving from 1 server. All chunks
              have to go into 1 folder. Duplicated names
              will get files overwritten.
            */

            filename: 'mf2/mf2Module.js'
        },
        devServer: {
            port: 3000,
            open: false,
        },
        devtool: 'inline-source-map',
        mode,
        resolve: {
            extensions: ['.ts', '.tsx', '.js'],
        },
        module: {
            rules: [
                {
                    test: /\.(js|jsx|tsx|ts)$/,
                    loader: 'ts-loader',
                    exclude: /node_modules/,
                }
            ],
        },
        plugins: [
            /*
              ---------------------------------------------------
              This needs to be modified for the new remote module
              ---------------------------------------------------
            */
            new ModuleFederationPlugin({
                name: 'mf2',
                /*
                  the remote module is held as filename
                */
                filename: 'remoteEntry.js',
                /*
                  it exposes components named  here
                */
                exposes: {
                    // './CounterModule': './src/components/Counter',
                    './AppModule': './src/App',
                },
                /*
                  this should be the same as the container one.
                */
                shared: {
                    ...deps,
                    react: { singleton: true, eager: true, requiredVersion: deps.react },
                    'react-dom': {
                        singleton: true,
                        eager: true,
                        requiredVersion: deps["react-dom"],
                    },
                },
            }),
            new HtmlWebpackPlugin({
                template: `./public/index.html`,
            }),
        ]
    };
};

Any ideas? I'm going crazy!!!

TIA

Cyberpunker
  • 113
  • 1
  • 2
  • 9

0 Answers0