Issue with Dynamic Chunk Loading in React Projects Using Webpack
Hello,
I am encountering an issue with dynamic chunk loading in two React projects named Host and Remote1, both running on React version 18.2.0 and created using Create React App (CRA).
Overview of the Setup:
- Projects Configuration:
- Both projects employ customize-cra and react-app-rewired to modify their configurations without ejecting. This is implemented through a config-overrides.js file at the root level of each project.
- We have a build-config.js script that dynamically builds a JavaScript file, which is then added to the public folder as global environment variables. This file is imported in the public HTML file, enabling us to alter configurations dynamically (like changing remote component addresses or toggling components at runtime).
- Modules Exposed:
- Host (http://localhost:3000/) exposes two modules:
- AuthProvider: A wrapper that handles authentication for both the Host and remote apps.
- preventCSSCollision: It manages CSS file tagging and enables/disables CSS files based on the active application.
- Remote1 (http://localhost:3001/) is set to only share itself.
Issue Description:
- Primary Problem:
- I encountered a chunk loading error when trying to load a chunk from the Remote1 component standalone. But it works inside the Host:
Error Message: Loading chunk vendors-node_modules_css-loader_dist_runtime_api_js-node_modules_css-loader_dist_runtime_sour-d924d0 failed. (missing: http://localhost:3001/static/js/vendors-node_modules_css-loader_dist_runtime_api_js-node_modules_css-loader_dist_runtime_sour-d924d0.chunk.js)
- Configuration Attempts:
- Setting config.output.publicPath = '/' in config-overrides.js ensures the Host application works correctly, but standalone Remote applications throw errors.
- Setting config.output.publicPath = 'auto' allows sub-routes of the remote component on the Host to function, but refreshing these pages results in failures (e.g., http://localhost:3000/remote1/page1).
- Attempts to set config.output.publicPath dynamically using webpack_public_path = window.location.origin + '/' have been unsuccessful.
Steps to Reproduce:
For a clearer understanding, I have created a simplified version of the projects and uploaded it to GitHub: dynamic-wmf-demo.
I would greatly appreciate any insights or suggestions on how to resolve this issue.
Thank you for your time and assistance.
I updated to code and examples of what I tried to solve problems to make it more clear.
Expected Behavior
- We should able to load Host and Remote1 standalone without error.
- We should able to browse Remote1 application sub routes on Host.
Example : http://localhost:3000/remote1/page2
- We should able to refresh the page while browse Remote1 applications sub routes on Host.
Example : http://localhost:3000/remote1/page3 (Hit refresh)
Problem
-
If config.output.publicPath = '/':
Browsing sub routes are work on the Host application including refreshing page while on sub routes but remote applications standalone throws error.
Error : Uncaught SyntaxError: Unexpected token '<'
-
If config.output.publicPath = 'auto',
While browsing sub routes on the Host and Remote1 works but when you on sub route on Host and refreshing the page causes error.
Error : Uncaught SyntaxError: Unexpected token '<'
-
If we set config.output.publicPath = 'http://localhost:3000/' everything works but it's not dynamic.
-
Instead of setting publicPath in config-overrides.js we can try to set webpack_public_path variable dynamically. We cerate a file ./src/dynamicPublicPath.ts with below content and import as very first item inside the entry point of Host app;
webpack_public_path = window.location.origin + '/'
-
Also tried to set config.output.publicPath = 'auto', '/' with ./src/dynamicPublicPath.ts. Result is same with previous attempts.
-
You might be able to set this with html attributes like base or something in the head tag to let browser know what base url is.
I cant remember the exact but theres a html head attr for setting base url.
We will be releasing a new version of federation soon. module-federation/universe repo is where you can track progress. In there youll have direct control over the MF lifecycle via runtime hooks and plugins for end users to enjoy
Hello @ScriptedAlchemy, thank you for your suggestion. I attempted to implement a static
if you cant do base path then youll have to use hard coded public paths for the time being. Check back once we release a new iteration of the plugin or finalize the runtime.
I have other options but they are complex and soon to be deprecated. We are adding middleware to MFP so you can have more control over it. But this nested issue is a problem only for the host.
Thank you, seems like I have to wait for the middleware.
module-federation.io