question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Webpack v5 - Module federation issue with loading chunks

See original GitHub issue

What is the current behavior? I moved from 5.beta.17 to the official 5.0.0 webpack version and the module federation project fails with with different errors as I think the main one is ChunkLoadError: Loading chunk src_components_admin_users_index_js failed.. Funny thing is that sometimes it works sometimes not. Sometimes its loading all the chunks sometimes not…

Both host and plugin projects live in S3 bucket and when I try to connect from my local pc to the s3 bucket for the plugin everything works smoothly. I don’t know how this chunk name was created as I don’t see it in the s3 bucket. I am developing a host and plugin project using module federation since the beginning and everything was ok until I move to 5.0.0. The 1st error which I get is: GET ... 404 ChunkLoadError: Loading chunk src_components_admin_users_index_js failed.. --> But there is not a chunk with this name at all…

2nd error which I get and it is super weird is about duplicated graphql packages. Screenshot 2020-10-13 at 9 48 43

** I had the same issue in the beginning but forcing the dep to be singleton worked perfectly before.

If the current behavior is a bug, please provide the steps to reproduce.

Host project: webpack.config:

/** @type {import('webpack').Configuration} */
module.exports = {
    output: {
        publicPath: dotenv.parsed.REACT_APP_PUBLIC_PATH,
        uniqueName: 'platform',
        filename: '[name].js',
        library: 'platform',
        chunkFilename: '[name][chunkhash].js'
    },
    devtool: 'source-map',
    cache: false,
    resolve: {
        extensions: ['.jsx', '.js', '.json'],
        alias: {... }
    },
    module: {
        rules: [
              .... loaders,
             // I leave this one here as I needed to do in order to run the project locally after migration to 5.00
            {
                test: /\.m?js/,
                resolve: {
                    fullySpecified: false
                }
            }
        ]
    },
    plugins: [
        new ModuleFederationPlugin({
            name: 'platform',
            library: { type: 'var', name: 'platform' },
            filename: 'remoteManifest.js',
            remotes: {
                app1: 'app1'
            },
            exposes: {
                 ....Components..
            },
            shared: {
                ...dependencies,
                react: {
                    eager: true,
                    singleton: true,
                    requiredVersion: dependencies.react
                },
                'react-dom': {
                    eager: true,
                    singleton: true,
                    requiredVersion: dependencies['react-dom']
                },
                'react-router-dom': {
                    eager: true,
                    singleton: true,
                    requiredVersion: dependencies['react-router-dom']
                },
                '@apollo/client': {
                    singleton: true,
                    requiredVersion: dependencies['@apollo/client']
                },
                graphql: {
                    singleton: true,
                    requiredVersion: dependencies['graphql']
                },
            }
        }),
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, 'public/index.html'),
            filename: './index.html',
            inject: true,
            favicon: path.resolve(__dirname, 'public/favicon.ico')
        })
    ]
};

webpack.config remote plugin:


/** @type {import('webpack').Configuration} */
module.exports = {
    output: {
        path: DIST_DIR,
        uniqueName: 'plugin',
        filename: '[name].js',
        library: 'plugin',
        chunkFilename: '[name][chunkhash].js',
        publicPath: dotenv.parsed.REACT_APP_PUBLIC_PATH
    },
    devtool: 'source-map',
    resolve: {
        extensions: ['.jsx', '.js', '.json'],
        alias: {}
    },
    devServer: {
        historyApiFallback: true,
        inline: true,
        port: parseInt(dotenv.parsed.PORT)
    },
    module: {
        rules: [
            loaders...,
            {
                test: /\.m?js/,
                type: 'javascript/auto',
                resolve: {
                    fullySpecified: false
                }
            }
        ]
    },
    plugins: [
        new ModuleFederationPlugin({
            name: 'app1',
            library: { type: 'var', name: 'app1' },
            filename: 'remoteManifest.js',
            remotes: {
                platform: 'platform'
            },
            exposes: {
              ....components
            },
            shared: {
                ...dependencies,
                react: {
                    singleton: true,
                    requiredVersion: dependencies.react
                },
                'react-dom': {
                    singleton: true,
                    requiredVersion: dependencies['react-dom']
                },
                '@apollo/client': {
                    singleton: true,
                    requiredVersion: dependencies['@apollo/client']
                },
                graphql: {
                    singleton: true,
                    requiredVersion: dependencies['graphql']
                }
            }
        })
    ]
};

And my package.json: ( they look pretty much the same in both ):

"scripts": {
    "start": "webpack-dev-server --mode development --liveReload",
    "build:prod": "webpack --mode production",
    "generate": "graphql-codegen --config codegen.yml",
    .. more scripts...
  },
  "dependencies": {
    "@apollo/client": "^3.2.3",
    "@babel/plugin-proposal-class-properties": "^7.10.4",
    "@babel/runtime": "^7.11.2",
    "dotenv": "^8.2.0",
    "exceljs": "^4.1.1",
    "file-saver": "^2.0.2",
    "graphql": "15.3.0",
    "jsdoc": "^3.6.4",
    "json-loader": "^0.5.7",
    "lodash": "^4.17.19",
    "mini-css-extract-plugin": "^0.9.0",
    "moment": "^2.27.0",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "react-flexa": "^0.9.1",
    "react-router-dom": "5.2.0",
    "react-select": "^3.1.0"
  },

Code to get remote scripts:

export const useDynamicScript = () => {
    const [ready, setReady] = useState(false);
    const [failed, setFailed] = useState(false);

    useEffect(() => {
        const fetchManifests = async (urls) => {
            Promise.all(urls.map((url) => loadScript(url))).then(() => setReady(true));
        };
        setReady(false);
        setFailed(false);

        let urls = Object.entries(process.env)
            .filter((x) => x[0].endsWith('PACKAGE'))
            .map((y) => y[1]);

        fetchManifests(urls);
    }, []);

    return {
        ready,
        failed
    };
};

export const loadComponent = (scope, module) => {
    return async () => {
        // Initializes the share scope. This fills it with known provided modules from this build and all remotes
        await __webpack_init_sharing__('default');
        const container = window[scope]; // or get the container somewhere else
        // Initialize the container, it may provide shared modules
        await container.init(__webpack_share_scopes__.default);
        const factory = await window[scope].get(module);
        const Module = factory();

        return Module;
    };
};

const loadScript = (url) =>
    new Promise((resolve) => {
        const element = document.createElement('script');
        element.async = true;
        element.src = `${url}remoteManifest.js`;
        element.type = 'text/javascript';

        document.head.appendChild(element);

        element.addEventListener('load', resolve, {
            once: true
        });
    });

What I tried?

  • Connecting to the s3 bucket from my local machine and everything works perfectly.
  • Adding resolutions in the package.jsons in both of the projects.
  • Clean installs multiple times
  • Singleton/Eager in both of them ( another topic is that I dont think its needed - just tried everything which I could think of)

What is the expected behavior?

It should load normally as its in local mode.

Other relevant information: webpack version: 5.0.0 Node.js version: 12.10 Operating System: Additional tools: Hosted in S3 bucket

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:18 (6 by maintainers)

github_iconTop GitHub Comments

8reactions
smasalacommented, May 31, 2021

Since NG 12 - I’m also having a similar issue where it’s trying to load the lazy loaded module on the host rather than from the remote origin.

3reactions
elenaschcommented, Apr 10, 2021

I was having a similar issue to 404 ChunkLoadError: Loading chunk src_components_admin_users_index_js failed, with host app running in hot replace mode but remote app without it. What finally helped was removing the optimization.runtimeChunk = 'single' setting

Read more comments on GitHub >

github_iconTop Results From Across the Web

Loading chunk | Module Federation webpack 5 while loading ...
This exception can arise when the public path of the remote module is misconfigured, so even if the app can access to the...
Read more >
Module Federation - webpack
Chunk loading should load everything needed in parallel (web: single round-trip to server). Control from consumer to container. Overriding modules is a one- ......
Read more >
Micro-frontends: Module Federation with WebPack 5
Is there a solution to this problem? There is, there are strategies to break that main.js file into chunks of smaller files in...
Read more >
How to Build a Micro Frontend with Webpack's Module ... - Bitovi
Meet Webpack's Module Federation plugin and learn how to build a ... that is bundled with Webpack 5.0 or greater can dynamically load...
Read more >
Revolutionizing Micro Frontends with Webpack 5, Module ...
Module Federation is a JavaScript architecture invented by Zack Jackson, ... This way, the initial application chunk from Webpack will load ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found