Webpack Module Federation fails with Next JS when using styled-components

Viewed 1834

I'm trying to get Webpack Module Federation working with a NextJS app where the federated module is using styled-components. My configuration is working as expected if I'm only using react and react-dom but using styled-components gives me these errors:

It looks like there are several instances of 'styled-components' initialized in this application. This may cause dynamic styles to not render properly, errors during the rehydration process, a missing theme prop, and makes your application bigger without good reason.

and

Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app

I have tried the different approaches to resolve styled-components to a single instance by modifying the Webpack config in both the host and remote apps, but all seem to fail.

Here is my current configuration:

Federated modules repo (webpack.config.js):

const { ModuleFederationPlugin } = require("webpack").container;
const deps = require("./package.json").dependencies;
const path = require("path");

module.exports = {
  mode: "development",
  devServer: {
    contentBase: path.join(__dirname, "dist"),
    port: 3001,
  },
  output: {
    publicPath: "auto",
  },
  resolve: {
    extensions: [".js"],
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: "babel-loader",
        exclude: /node_modules/,
        options: {
          plugins: [
            ["babel-plugin-styled-components", { pure: true, ssr: true }],
          ],
          presets: ["@babel/preset-react"],
        },
      },
    ],
  },
  plugins: [
    new ModuleFederationPlugin({
      name: "remoteLib",
      filename: "remoteEntry.js",
      exposes: {
        "./Button": "./src/Button",
      },
      shared: {
        ...deps,
        react: {
          singleton: true,
          requiredVersion: deps.react,
        },
        "react-dom": {
          singleton: true,
          requiredVersion: deps["react-dom"],
        },
        "styled-components": {
          singleton: true,
          requiredVersion: deps["styled-components"],
        },
      },
    }),
  ],
};

Consuming NextJS app Webpack config (next.config.js):

webpack: (config, options) => {
    const { ModuleFederationPlugin } = options.webpack.container;

    config.plugins.push(
        new ModuleFederationPlugin({
            remotes: {
                'federated-components': 'remoteLib@http://localhost:3001/remoteEntry.js'
            }
        })
    );

    return config;
}
0 Answers
Related