reactjswebpackwebpack-module-federation

Microfrontend Module federation Uncaught (in promise) TypeError: fn is not a function error


I am trying to create a sample microfrontend in react which contains Products app and the container app

products app's webpack.config.js

const htmlWebPackPlugin=require('html-webpack-plugin');
const moduleFederationPlugin=require('webpack/lib/container/ModuleFederationPlugin');
module.exports={
  devtool:"eval-source-map",
  mode:'development',
  devServer:{
    port:8081
  },
  plugins:[
    new moduleFederationPlugin({
      name:'products',
      filename:'remoteEntry.js',
      exposes:{
        './productsIndex':'./src/index'
      }
    }),
    new htmlWebPackPlugin({
        template:'./public/index.html'
    })
  ]
};

index.js file

import faker from 'faker';

let products='';

for (let index = 0; index < 5; index++) {
    products+=`<div>${faker.commerce.productName()}</div>`;
}

document.querySelector('#products').innerHTML=products;

product app's index.html

<html>
    <head></head>
    <body>
        <div id="products"></div>
    </body>
</html>

container app's webpack.config.js

const htmlWebPackPlugin=require('html-webpack-plugin');
const moduleFederationPlugin=require('webpack/lib/container/ModuleFederationPlugin');
module.exports={
    devtool:"eval-source-map",
    mode:'development',
    devServer:{
        port:8080
    },
    plugins:[
        new moduleFederationPlugin({
            name:'containers',
            remotes:{
                products:'products@http://localhost:8081/remoteEntry.js'
            }
          }),
       new htmlWebPackPlugin({
         template:'./public/index.html'
       })
    ]
};

container app's bootstrap.js

import 'products/productsIndex';
console.log('container');

container app's index.js

import('./bootstrap');

container app's index.html

<html>
    <head></head>
    <body>
        <div id="products"></div>
    </body>
</html>

When I run the container app, remote files are loading fine but getting error as

Uncaught (in promise) TypeError: fn is not a function
while loading "./productsIndex" from webpack/container/reference/products
    at handleFunction (main.js:500:31)
    at onInitialized (main.js:512:60)
    at main.js:502:52
    at async Promise.all (:8080/index 0)

Solution

  • Found the reason for this error, when the remote name given in Module Federation Plugin and the id given to dom element in remote HTML are same, this error will come

    In this case, inside the product's moduleFederation config name is 'products' and in the container app's index.html has a div with id 'products', to fix the issue just have to change the name in any one place

    The reason for this behavior is, that remoteEntry.js will create a global variable as remote name (that is var cart;) and when we have a dom element with id, the browser creates a global variable with the same id, so the variable created on the dom element will override the variable created by remoteEntry.js