4

I'm try to Connect my federated module from server side with React.lazy. My same issue in @module-federation/node repo (https://github.com/module-federation/universe/issues/493)

I have custom React ssr server. (https://github.com/ignatiqq/react-ssr-blog/blob/master/src/server/modules/render/render.tsx)

I'm import it like this:

const Homepage = React.lazy(() => import('homePage/Homepage'));

// router code

{path: '/overview', element: <Homepage />},

On client all works ok. But on server i have problems with the above error.

enter image description here

deps:

"@module-federation/node": "^0.9.11",
"react": "^18.2.0",
"webpack": "^5.74.0",

shell app webpack config (client):

 {
    name: 'client',
    target: 'web',
    entry: {
        client: path.resolve(__dirname, '../../src/client/index.ts'),
    },
    output: {
        path: path.resolve(__dirname, '../../dist/client'),
        filename: 'js/[name].[contenthash].js',
        publicPath: '/static/',
        clean: true,
        assetModuleFilename: 'images/[hash][ext]',
    },
    optimization: {
        moduleIds: 'deterministic',
        minimize: !isDev ? true : false,
        minimizer: !isDev ? [new TerserPlugin()] : [],
    },
    module: {
        rules: [
            ...rules,
            {
                test: /\.s[ac]ss$/i,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'sass-loader',
                ],
            },
        ],
    },
    plugins: [
        ...plugins.client,
    ],
};

Webpack plugin part of shell app:

const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
const {NodeFederationPlugin, StreamingTargetPlugin} = require('@module-federation/node');

const path = require('path');

const dependencies = require(path.join(__dirname, '../../../package.json')).dependencies;

const remotes = {
    server: {
        homePage: 'homePage@http://localhost:8080/server/homePageRemote.js',
    },
    client: {
        homePage: 'homePage@http://localhost:8080/client/homePageRemote.js',
    },
};

module.exports = {
    client: [
        new ModuleFederationPlugin({
            name: 'shellApp',
            remotes: {...remotes.client},
            shared: {
                react: {
                    singleton: true,
                    requiredVersion: dependencies['react'],
                },
                'react-dom': {
                    singleton: true,
                    requiredVersion: dependencies['react-dom'],
                },
            },
        }),
    ],
    server: [
        new NodeFederationPlugin({
            name: 'shellApp',
            library: {type: 'commonjs-module'},
            remotes: {...remotes.server},
            shared: {
                react: {
                    singleton: true,
                    requiredVersion: dependencies['react'],
                },
                'react-dom': {
                    singleton: true,
                    requiredVersion: dependencies['react-dom'],
                },
            },
        }),
        new StreamingTargetPlugin({
            name: 'shellApp',
            library: { type: 'commonjs-module' },
            remotes: {...remotes.server},
        }),
    ],
};

Webpack part of remote app: https://github.com/ignatiqq/hp-microfront-for-ssr-blog/blob/master/webpack/server/webpack.server.js

const path = require('path');
const mainRules = require('../additionally/rules');
const { NodeFederationPlugin, StreamingTargetPlugin } = require('@module-federation/node');
const extensions = require('../additionally/extensions');

const mode = process.env.NODE_ENV === 'development' ? 'development' : 'production';
const isDev = mode === 'development';

const dependencies = require('../../package.json').dependencies;

module.exports = {
    entry: {
        server: path.join(__dirname, '../../src/index.tsx')
    },
    stats: {
        colors: true,
        entrypoints: false,
        children: false,
    },
    target: false,
    output: {
        path: path.join(__dirname, '../../dist/server'),
        filename: '[name].[contenthash].js',
        clean: true,
        publicPath: 'http://localhost:8080/server',
    },
    resolve: {
        extensions,
    },
    devtool: isDev ? 'inline-source-map' : 'source-map',
    module: {
        rules: [
            ...mainRules,
            {
                test: /\.(css|scss)$/i,
                    use: [
                    {
                        loader: "css-loader",
                    },
                    {
                        loader: "sass-loader",
                    },
                ],
                exclude: /node_modules/
            }
        ],
    },
    plugins: [
        new NodeFederationPlugin({
            name: 'homePage',
            filename: 'homePageRemote.js',
            library: { type: "commonjs-module" },
            remotes: {},
            exposes: {
                './Homepage': path.resolve(__dirname, '../../src/Homepage.tsx'),
            },
            shared: {
                react: {
                    singleton: true,
                    requiredVersion: dependencies['react'],
                },
                'react-dom': {
                    singleton: true,
                    requiredVersion: dependencies['react-dom'],
                }
            }
        }),
        new StreamingTargetPlugin({
            name: 'homePage',
            library: { type: "commonjs-module" },
            remotes: {},
            shared: {
                react: {
                    singleton: true,
                    requiredVersion: dependencies['react'],
                },
                'react-dom': {
                    singleton: true,
                    requiredVersion: dependencies['react-dom'],
                }
            }
        })
    ]
}

Can someone help me please? Why dependencies are not sharing?

UPD: UniversalFederationPlugin throws same error

2 Answers 2

0

Adding externals: { react: "react" } to server webpack config of remote fixes issue.

Sign up to request clarification or add additional context in comments.

3 Comments

Hello, ty. Why do we need to external react deps? Now i have this issue: "Uncaught Error: react is not defined while loading "./Homepage" from webpack/container/reference/homePage " I believe that's mf work to exclude react deps by "shared" field in config
unfortunately it didn't help me. I have same error - "Uncaught Error: react is not defined while loading "./Homepage" from webpack/container/reference/homePage "
-1

For me solution was adding node-fetch package, that is required by mf remoteEntry build

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.