Skip to content
Advertisement

ModuleFederationPlugin remote module is not being loaded

I have two apps.

  1. Container. Webpack
const baseConfig = {
  mode: 'development',
  resolve: {
    extensions: ['.ts', '.tsx', '.js', '.jsx'],
  },
  entry: {
    main: './src/index.tsx',
  },
  module: {
    rules: [
      {
        test: /.tsx?$/,
        use: 'ts-loader',
        exclude: '/node_modules/',
      }
    ],
  },

  devServer: { hot: false, contentBase: path.join(__dirname, 'dist'), port: 3100 },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'dist'),
    chunkFilename: '[id].[contenthash].js',
  },
  plugins: [
    new ModuleFederationPlugin({
      name: 'Shell',
      library: { type: 'var', name: 'shell' },
      remotes: {
        usersweb: 'usersweb',
      },
      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',
    }),
  ],

}

App.tsx

import React from 'react'

const Portal = React.lazy(() => import('usersweb/Portal'))

export default function Shell() {
  return (
    <React.Suspense fallback={'Loading'}>
      <Portal />
    </React.Suspense>
  )
}

2nd App. Webpack

const baseConfig = {
  mode: 'development',
  resolve: {
    extensions: ['.ts', '.tsx', '.js', '.jsx'],
  },
  module: {
    rules: [
      {
        test: /.tsx?$/,
        use: 'ts-loader',
        exclude: '/node_modules/',
      }
    ],
  },
  entry: {
    main: './src/index.tsx',
  },
  output: {
    chunkFilename: '[id].[contenthash].js',
    path: path.resolve(__dirname, 'dist'),
  },
  devServer: { contentBase: path.join(__dirname, 'dist'), port: 3101 },

  plugins: [
    new ModuleFederationPlugin({
      filename: 'remoteEntry.js',
      name: 'usersweb',
      exposes: {
        './Portal': './src/portal',
      },
      shared: {
        ...deps,
        react: { singleton: true, eager: true, requiredVersion: deps.react },
        'react-dom': { singleton: true, eager: true, requiredVersion: deps['react-dom'] },
      },
    }),
  ],
}

./src/portal.tsx

import React from 'react'

const Portal: React.FC = () => {
  return <div>Hello from userweb</div>
}

export default Portal

It should work smooth.

But it is failing because inside of webpack_modules exists webpack/container/reference/usersweb key, but when React.Lazy requiring remote model it is requiring
webpack/container/remote/usersweb/Portalscript which is not added and app crashes.

remoteEntry.js loaded properly and I may see userweb object in the console.

dependencies versions

“react”: “^17.0.2”, “webpack”: “5.21.2”, “typescript”: “^4.1.2”,

Advertisement

Answer

After 5 days debugging issue was in tsconfig.json

In order to proper load modules with ‘ts-loader’ need to add to compilerOptions

  "module": "esnext",
Advertisement