webpackwebpack-module-federation

Module federation React is not defined at App


I have a simple remote app with the configuration below, but when I try to load it in the host app react seems not properly loaded despite being in the shared libraries. What might be the issue?

Uncaught ReferenceError: React is not defined
    at App (App.tsx:6:3)
    at renderWithHooks (react-dom.development.js:15486:18)
    at mountIndeterminateComponent (react-dom.development.js:20098:13)

webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin');
const ModuleFederationPlugin =
  require('@module-federation/enhanced').ModuleFederationPlugin;
const path = require('path');

module.exports = {
  entry: './src/main.tsx',
  mode: 'development',
  target: 'web',
  devServer: {
    static: {
      directory: path.join(__dirname, 'dist'),
    },
    port: 4200,
  },
  optimization: {
    runtimeChunk: false,
    splitChunks: {
      chunks: 'async',
    },
  },
  output: {
    publicPath: 'auto',
    path: path.join(__dirname, '../../dist/apps/remote_webpack'),
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
  module: {
    rules: [
      {
        test: /\.(ts|tsx)?$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
      },
    ],
  },
  plugins: [
    new ModuleFederationPlugin({
      name: 'remote_webpack',
      filename: 'remoteEntry.js',
      exposes: {
        './Module': './src/remote-entry.ts',
      },
      shared: {
        react: {
          import: 'react',
          shareKey: 'react',
          shareScope: 'default',
          singleton: true,
        },
        'react-dom': {
          singleton: true,
        },
      },
    }),
    new HtmlWebpackPlugin({
      template: './src/index.html',
    }),
  ],
};

Solution

  • React < 17

    We need to explicitly import React in every file

    React >= 17

    The issue was related to babel. Either in options > presets in the rule for babel-loader in webpack.config.json or in a .babelrc file we need to specify runtime:"automatic" for @babel/preset-react.

    .babelrc

    {
      "presets": [
        "@babel/preset-env",
        "@babel/preset-typescript",
        ["@babel/preset-react", { "runtime": "automatic" }]
      ],
      "plugins": []
    }