{"id":17485576,"url":"https://github.com/patricklafrance/wmf-versioning","last_synced_at":"2026-04-13T20:02:24.948Z","repository":{"id":161225598,"uuid":"633672137","full_name":"patricklafrance/wmf-versioning","owner":"patricklafrance","description":"POC to test Webpack Module Federation shared dependency versioning capabilities","archived":false,"fork":false,"pushed_at":"2023-09-19T17:22:28.000Z","size":67,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-10-19T05:21:55.448Z","etag":null,"topics":["module-federation","react","react-router","webpack"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/patricklafrance.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-04-28T02:57:00.000Z","updated_at":"2023-10-06T15:31:17.000Z","dependencies_parsed_at":null,"dependency_job_id":"ea2a16ac-8b07-44e3-9ed1-83cb7930e544","html_url":"https://github.com/patricklafrance/wmf-versioning","commit_stats":{"total_commits":6,"total_committers":2,"mean_commits":3.0,"dds":"0.16666666666666663","last_synced_commit":"345fdd54a4108dc69e6d6c5e69726be18c499013"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":"patricklafrance/wmf-poc-template","purl":"pkg:github/patricklafrance/wmf-versioning","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patricklafrance%2Fwmf-versioning","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patricklafrance%2Fwmf-versioning/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patricklafrance%2Fwmf-versioning/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patricklafrance%2Fwmf-versioning/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/patricklafrance","download_url":"https://codeload.github.com/patricklafrance/wmf-versioning/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patricklafrance%2Fwmf-versioning/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31768649,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-13T15:25:13.801Z","status":"ssl_error","status_checked_at":"2026-04-13T15:25:09.162Z","response_time":93,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["module-federation","react","react-router","webpack"],"created_at":"2024-10-19T02:08:10.450Z","updated_at":"2026-04-13T20:02:24.930Z","avatar_url":"https://github.com/patricklafrance.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# wmf-versioning\n\n## Usage\n\nThe repository contains 3 applications:\n- An [host application](./packages/host/)\n- A remote module named [remote-1](./packages/remote-1/)\n- A remote module named [remote-2](./packages/remote-2/)\n\nFirst install the dependencies with PNPM:\n\n```bash\npnpm install\n```\n\n### Development server\n\nTo start the application in dev mode (make sure ports 8080, 8081 and 8082 are available):\n\n```bash\npnpm dev\n```\n\nOpen a browser at http://localhost:8080/.\n\nThe remote module entries are available at:\n- http://localhost:8081/remoteEntry.js for remote-1\n- http://localhost:8082/remoteEntry.js for remote-2\n\nIf you prefer to start the application and modules separately:\n\n```bash\ncd packages/host\npnpm dev\n```\n\n```bash\ncd packages/remote-1\npnpm dev\n```\n\n```bash\ncd packages/remote-2\npnpm dev\n```\n\n### Production build\n\nTo start the application with production build (make sure ports 8080, 8081 and 8082 are available):\n\n```bash\npnpm serve-build\n```\n\n## Learnings\n\n### When no dependencies are shared\n\nWith the host application and both remotes having:\n\n- `react` version `18.2.0`\n- `react-dom` version `18.2.0`\n- `useless-lib` version `3.0.0`\n\nAnd the following `ModuleFederationPlugin` config:\n\n```js\n// host/webpack.dev.js - 8080\n\nnew ModuleFederationPlugin({\n    name: \"host\",\n    remotes: {\n        remote1: \"remote1@http://localhost:8081/remoteEntry.js\",\n        remote2: \"remote2@http://localhost:8082/remoteEntry.js\"\n    }\n})\n```\n\n```js\n// remote-1/webpack.dev.js - 8081\n\nnew ModuleFederationPlugin({\n    name: \"remote1\",\n    filename: \"remoteEntry.js\",\n    exposes: {\n        \"./HelloWorld.jsx\": \"./src/HelloWorld.jsx\"\n    }\n})\n```\n\n```js\n// remote-2/webpack.dev.js - 8082\n\nnew ModuleFederationPlugin({\n    name: \"remote2\",\n    filename: \"remoteEntry.js\",\n    exposes: {\n        \"./HelloWorld.jsx\": \"./src/HelloWorld.jsx\"\n    }\n})\n```\n\n`react`, `react-dom` and `useless-lib` are included in the host application bundle and both remote module bundles:\n\n- http://localhost:8080/vendors-node_modules_pnpm_react-dom_18_2_0_react_18_2_0_node_modules_react-dom_client_js-node-780c21.js\n- http://localhost:8081/vendors-node_modules_pnpm_react_18_2_0_node_modules_react_jsx-runtime_js-node_modules_pnpm_us-d19814.js\n- http://localhost:8082/vendors-node_modules_pnpm_react_18_2_0_node_modules_react_jsx-runtime_js-node_modules_pnpm_us-cf5ae6.js\n\n### When a dependency is shared without any option\n\nWith the host application and both remotes having:\n\n- `react` version `18.2.0`\n- `react-dom` version `18.2.0`\n- `useless-lib` version `3.0.0`\n\nAnd the following `ModuleFederationPlugin` config:\n\n```js\n// host/webpack.dev.js - 8080\n\nnew ModuleFederationPlugin({\n    name: \"host\",\n    remotes: {\n        remote1: \"remote1@http://localhost:8081/remoteEntry.js\",\n        remote2: \"remote2@http://localhost:8082/remoteEntry.js\"\n    },\n    shared: [\"react\", \"react-dom\", \"useless-lib\"] \u003c------\n})\n```\n\n```js\n// remote-1/webpack.dev.js - 8081\n\nnew ModuleFederationPlugin({\n    name: \"remote1\",\n    filename: \"remoteEntry.js\",\n    exposes: {\n        \"./HelloWorld.jsx\": \"./src/HelloWorld.jsx\"\n    },\n    shared: [\"react\", \"react-dom\", \"useless-lib\"] \u003c------\n})\n```\n\n```js\n// remote-2/webpack.dev.js - 8082\n\nnew ModuleFederationPlugin({\n    name: \"remote2\",\n    filename: \"remoteEntry.js\",\n    exposes: {\n        \"./HelloWorld.jsx\": \"./src/HelloWorld.jsx\"\n    },\n    shared: [\"react\", \"react-dom\", \"useless-lib\"] \u003c------\n})\n```\n\n`react`, `react-dom` and `useless-lib` are included once:\n\n- http://localhost:8082/vendors-node_modules_pnpm_react_18_2_0_node_modules_react_index_js.js (react)\n- http://localhost:8080/vendors-node_modules_pnpm_react-dom_18_2_0_react_18_2_0_node_modules_react-dom_index_js.js (react-dom)\n- http://localhost:8082/node_modules_pnpm_useless-lib_3_0_0_node_modules_useless-lib_index_js.js (useless-lib)\n\n#### When the remote dependency version differs\n\nWith the following dependencies:\n\n```js\n// host/package.json\n\n{\n    \"react\": \"18.2.0\",\n    \"react-dom\": \"18.2.0\",\n    \"useless-lib\": \"2.0.0\" \u003c------\n}\n```\n\n```js\n// remote-1/package.json\n\n{\n    \"react\": \"18.2.0\",\n    \"react-dom\": \"18.2.0\",\n    \"useless-lib\": \"2.1.0\" \u003c------\n}\n```\n\n```js\n// remote-2/package.json\n\n{\n    \"react\": \"18.2.0\",\n    \"react-dom\": \"18.2.0\",\n    \"useless-lib\": \"2.0.0\" \u003c------\n}\n```\n\n2 versions of the `useless-lib` dependency is loaded:\n\n- http://localhost:8082/vendors-node_modules_pnpm_react_18_2_0_node_modules_react_index_js.js (react)\n- http://localhost:8080/vendors-node_modules_pnpm_react-dom_18_2_0_react_18_2_0_node_modules_react-dom_index_js.js (react-dom)\n- http://localhost:8082/node_modules_pnpm_useless-lib_2_0_0_node_modules_useless-lib_index_js.js (useless-lib 2.0) \u003c------\n- http://localhost:8081/node_modules_pnpm_useless-lib_2_1_0_node_modules_useless-lib_index_js.js (useless-lib 2.1) \u003c------\n\n### When a dependendy is shared as a singleton\n\nWith the host application and both remotes having:\n\n- `react` version `18.2.0`\n- `react-dom` version `18.2.0`\n- `useless-lib` version `3.0.0`\n\nAnd the following `ModuleFederationPlugin` config:\n\n```js\n// host/webpack.dev.js - 8080\n\nnew ModuleFederationPlugin({\n    name: \"host\",\n    remotes: {\n        remote1: \"remote1@http://localhost:8081/remoteEntry.js\",\n        remote2: \"remote2@http://localhost:8082/remoteEntry.js\"\n    },\n    shared: {\n        \"react\": {\n            singleton: true\n        },\n        \"react-dom\": {\n            singleton: true\n        },\n        \"useless-lib\": {\n            singleton: true\n        }\n    }\n})\n```\n\n```js\n// remote-1/webpack.dev.js - 8081\n\nnew ModuleFederationPlugin({\n    name: \"remote1\",\n    filename: \"remoteEntry.js\",\n    exposes: {\n        \"./HelloWorld.jsx\": \"./src/HelloWorld.jsx\"\n    },\n    shared: {\n        \"react\": {\n            singleton: true\n        },\n        \"react-dom\": {\n            singleton: true\n        },\n        \"useless-lib\": {\n            singleton: true\n        }\n    }\n})\n```\n\n```js\n// remote-2/webpack.dev.js - 8082\n\nnew ModuleFederationPlugin({\n    name: \"remote2\",\n    filename: \"remoteEntry.js\",\n    exposes: {\n        \"./HelloWorld.jsx\": \"./src/HelloWorld.jsx\"\n    },\n    shared: {\n        \"react\": {\n            singleton: true\n        },\n        \"react-dom\": {\n            singleton: true\n        },\n        \"useless-lib\": {\n            singleton: true\n        }\n    }\n})\n```\n\n`react`, `react-dom` and `useless-lib` are included once:\n\n- http://localhost:8082/vendors-node_modules_pnpm_react_18_2_0_node_modules_react_index_js.js (react)\n- http://localhost:8080/vendors-node_modules_pnpm_react-dom_18_2_0_react_18_2_0_node_modules_react-dom_index_js.js (react-dom)\n- http://localhost:8082/node_modules_pnpm_useless-lib_3_0_0_node_modules_useless-lib_index_js.js (useless-lib)\n\n#### When the remote dependency version differs but is compatible (not a different major version)\n\nWith the following dependencies:\n\n```js\n// host/package.json\n\n{\n    \"react\": \"18.2.0\",\n    \"react-dom\": \"18.2.0\",\n    \"useless-lib\": \"2.0.0\" \u003c------\n}\n```\n\n```js\n// remote-1/package.json\n\n{\n    \"react\": \"18.2.0\",\n    \"react-dom\": \"18.2.0\",\n    \"useless-lib\": \"2.1.0\" \u003c------\n}\n```\n\n```js\n// remote-2/package.json\n\n{\n    \"react\": \"18.2.0\",\n    \"react-dom\": \"18.2.0\",\n    \"useless-lib\": \"2.0.0\" \u003c------\n}\n```\n\n`react`, `react-dom` and `useless-lib` are included once, 2.1.0 is loaded for `useless-lib` as it is the highest compatible version:\n\n- http://localhost:8082/vendors-node_modules_pnpm_react_18_2_0_node_modules_react_index_js.js (react)\n- http://localhost:8080/vendors-node_modules_pnpm_react-dom_18_2_0_react_18_2_0_node_modules_react-dom_index_js.js (react-dom)\n- http://localhost:8081/node_modules_pnpm_useless-lib_2_1_0_node_modules_useless-lib_index_js.js (useless-lib)\n\n#### When the host dependency version differs from a remote required version\n\nWith the following dependencies:\n\n```js\n// host/package.json\n\n{\n    \"react\": \"18.2.0\",\n    \"react-dom\": \"18.2.0\",\n    \"useless-lib\": \"2.0.0\" \u003c------\n}\n```\n\n```js\n// remote-1/package.json\n\n{\n    \"react\": \"18.2.0\",\n    \"react-dom\": \"18.2.0\",\n    \"useless-lib\": \"2.1.0\" \u003c------\n}\n```\n\n```js\n// remote-2/package.json\n\n{\n    \"react\": \"18.2.0\",\n    \"react-dom\": \"18.2.0\",\n    \"useless-lib\": \"2.0.0\" \u003c------\n}\n```\n\nAnd the following `ModuleFederationPlugin` config:\n\n```js\n// host/webpack.dev.js - 8080\n\nnew ModuleFederationPlugin({\n    name: \"host\",\n    remotes: {\n        remote1: \"remote1@http://localhost:8081/remoteEntry.js\",\n        remote2: \"remote2@http://localhost:8082/remoteEntry.js\"\n    },\n    shared: {\n        \"react\": {\n            singleton: true\n        },\n        \"react-dom\": {\n            singleton: true\n        },\n        \"useless-lib\": {\n            singleton: true\n        }\n    }\n})\n```\n\n```js\n// remote-1/webpack.dev.js - 8081\n\nnew ModuleFederationPlugin({\n    name: \"remote1\",\n    filename: \"remoteEntry.js\",\n    exposes: {\n        \"./HelloWorld.jsx\": \"./src/HelloWorld.jsx\"\n    },\n    shared: {\n        \"react\": {\n            singleton: true\n        },\n        \"react-dom\": {\n            singleton: true\n        },\n        \"useless-lib\": {\n            singleton: true,\n            requiredVersion: \"2.1.0\", \u003c------\n            strictVersion: true \u003c------\n        }\n    }\n})\n```\n\n```js\n// remote-2/webpack.dev.js - 8082\n\nnew ModuleFederationPlugin({\n    name: \"remote2\",\n    filename: \"remoteEntry.js\",\n    exposes: {\n        \"./HelloWorld.jsx\": \"./src/HelloWorld.jsx\"\n    },\n    shared: {\n        \"react\": {\n            singleton: true\n        },\n        \"react-dom\": {\n            singleton: true\n        },\n        \"useless-lib\": {\n            singleton: true\n        }\n    }\n})\n```\n\nThe following warning is printed and the host application and the remote modules used version 2.1 (which seems suspicious)\n\n\u003e Unsatisfied version 2.1.0 from remote-1 of shared singleton module useless-lib (required =2.0.0)\n\n#### Same test as the previous one but with the host application and remote-2 also specifying a requiredVersion\n\n```js\n// remote-2/package.json\n\n{\n    \"react\": \"18.2.0\",\n    \"react-dom\": \"18.2.0\",\n    \"useless-lib\": \"2.0.0\" \u003c------\n}\n```\n\nAnd the following `ModuleFederationPlugin` config:\n\n```js\n// host/webpack.dev.js - 8080\n\nnew ModuleFederationPlugin({\n    name: \"host\",\n    remotes: {\n        remote1: \"remote1@http://localhost:8081/remoteEntry.js\",\n        remote2: \"remote2@http://localhost:8082/remoteEntry.js\"\n    },\n    shared: {\n        \"react\": {\n            singleton: true\n        },\n        \"react-dom\": {\n            singleton: true\n        },\n        \"useless-lib\": {\n            singleton: true,\n            requiredVersion: \"2.0.0\", \u003c------\n            strictVersion: true \u003c------\n        }\n    }\n})\n```\n\n```js\n// remote-1/webpack.dev.js - 8081\n\nnew ModuleFederationPlugin({\n    name: \"remote1\",\n    filename: \"remoteEntry.js\",\n    exposes: {\n        \"./HelloWorld.jsx\": \"./src/HelloWorld.jsx\"\n    },\n    shared: {\n        \"react\": {\n            singleton: true\n        },\n        \"react-dom\": {\n            singleton: true\n        },\n        \"useless-lib\": {\n            singleton: true,\n            requiredVersion: \"2.1.0\", \u003c------\n            strictVersion: true \u003c------\n        }\n    }\n})\n```\n\n```js\n// remote-2/webpack.dev.js - 8082\n\nnew ModuleFederationPlugin({\n    name: \"remote2\",\n    filename: \"remoteEntry.js\",\n    exposes: {\n        \"./HelloWorld.jsx\": \"./src/HelloWorld.jsx\"\n    },\n    shared: {\n        \"react\": {\n            singleton: true\n        },\n        \"react-dom\": {\n            singleton: true\n        },\n        \"useless-lib\": {\n            singleton: true,\n            requiredVersion: \"2.0.0\", \u003c------\n            strictVersion: true \u003c------\n        }\n    }\n})\n```\n\nThe following error is thrown:\n\n\u003e Uncaught (in promise) Error: Unsatisfied version 2.1.0 from remote-1 of shared singleton module useless-lib (required =2.0.0)\n\n### When a dependency is eagerly loaded\n\nWith the following dependencies:\n\n```js\n// host/package.json\n\n{\n    \"react\": \"18.2.0\",\n    \"react-dom\": \"18.2.0\",\n    \"useless-lib\": \"3.0.0\"\n}\n```\n\n```js\n// remote-1/package.json\n\n{\n    \"react\": \"18.2.0\",\n    \"react-dom\": \"18.2.0\",\n    \"useless-lib\": \"3.0.0\"\n}\n```\n\n```js\n// remote-2/package.json\n\n{\n    \"react\": \"18.2.0\",\n    \"react-dom\": \"18.2.0\",\n    \"useless-lib\": \"3.0.0\"\n}\n```\n\nAnd the following `ModuleFederationPlugin` config:\n\n```js\n// host/webpack.dev.js - 8080\n\nnew ModuleFederationPlugin({\n    name: \"host\",\n    remotes: {\n        remote1: \"remote1@http://localhost:8081/remoteEntry.js\",\n        remote2: \"remote2@http://localhost:8082/remoteEntry.js\"\n    },\n    shared: {\n        \"react\": {\n            singleton: true\n        },\n        \"react-dom\": {\n            singleton: true\n        },\n        \"useless-lib\": {\n            eager: true \u003c------\n        }\n    }\n})\n```\n\n```js\n// remote-1/webpack.dev.js - 8081\n\nnew ModuleFederationPlugin({\n    name: \"remote1\",\n    filename: \"remoteEntry.js\",\n    exposes: {\n        \"./HelloWorld.jsx\": \"./src/HelloWorld.jsx\"\n    },\n    shared: {\n        \"react\": {\n            singleton: true\n        },\n        \"react-dom\": {\n            singleton: true\n        },\n        \"useless-lib\": {}\n})\n```\n\n```js\n// remote-2/webpack.dev.js - 8082\n\nnew ModuleFederationPlugin({\n    name: \"remote2\",\n    filename: \"remoteEntry.js\",\n    exposes: {\n        \"./HelloWorld.jsx\": \"./src/HelloWorld.jsx\"\n    },\n    shared: {\n        \"react\": {\n            singleton: true\n        },\n        \"react-dom\": {\n            singleton: true\n        },\n        \"useless-lib\": {}\n    }\n})\n```\n\n`react`, `react-dom` and `useless-lib` are included once and `useless-libs` is included in the main bundle rather than it's own file:\n\n- http://localhost:8082/vendors-node_modules_pnpm_react_18_2_0_node_modules_react_index_js.js (react)\n- http://localhost:8080/vendors-node_modules_pnpm_react-dom_18_2_0_react_18_2_0_node_modules_react-dom_index_js.js (react-dom)\n- http://localhost:8080/main.js (useless-lib)\n\n**It is super important that `eager` is only defined in the host application. If `eager` was to be also defined for `useless-lib` in the remote modules, it would be included in all the bundles (`main.js`, `remoteEntry.js:8081`, `remoteEntry.js:8082`)**\n\n### Using React 17 and React 18 in parallel\n\nWith the following dependencies:\n\n```js\n// host/package.json\n\n{\n    \"react\": \"18.2.0\",\n    \"react-dom\": \"18.2.0\",\n    \"useless-lib\": \"3.0.0\",\n    \"shared\": \"workspace:*\"\n}\n```\n\n```js\n// remote-1/package.json\n\n{\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"useless-lib\": \"3.0.0\",\n    \"shared\": \"workspace:*\"\n}\n```\n\n```js\n// remote-2/package.json\n\n{\n    \"react\": \"18.2.0\",\n    \"react-dom\": \"18.2.0\",\n    \"useless-lib\": \"3.0.0\",\n    \"shared\": \"workspace:*\"\n}\n```\n\nAnd the following `ModuleFederationPlugin` config:\n\n```js\n// host/webpack.dev.js - 8080\n\nnew ModuleFederationPlugin({\n    name: \"host\",\n    remotes: {\n        remote1: \"remote1@http://localhost:8081/remoteEntry.js\",\n        remote2: \"remote2@http://localhost:8082/remoteEntry.js\"\n    },\n    shared: {\n        \"react\": {\n            singleton: true\n        },\n        \"react-dom\": {\n            singleton: true\n        },\n        \"shared\": {\n            singleton: true\n        },\n        \"useless-lib\": {}\n    }\n})\n```\n\n```js\n// remote-1/webpack.dev.js - 8081\n\nnew ModuleFederationPlugin({\n    name: \"remote1\",\n    filename: \"remoteEntry.js\",\n    exposes: {\n        \"./HelloWorld.jsx\": \"./src/HelloWorld.jsx\"\n    },\n    shared: {\n        \"react\": {\n            singleton: true\n        },\n        \"react-dom\": {\n            singleton: true\n        },\n        \"shared\": {\n            singleton: true\n        },\n        \"useless-lib\": {}\n})\n```\n\n```js\n// remote-2/webpack.dev.js - 8082\n\nnew ModuleFederationPlugin({\n    name: \"remote2\",\n    filename: \"remoteEntry.js\",\n    exposes: {\n        \"./HelloWorld.jsx\": \"./src/HelloWorld.jsx\"\n    },\n    shared: {\n        \"react\": {\n            singleton: true\n        },\n        \"react-dom\": {\n            singleton: true\n        },\n        \"shared\": {\n            singleton: true\n        },\n        \"useless-lib\": {}\n    }\n})\n```\n\nSince `react` 18 is kind of backward compatible with `react` 17 everything seems to work fine. Because `react` is defined as a shared \"singleton\", ONLY react **18.2.0** is loaded.\n\nThat wouldn't work thought if \"remote-1\" is using something that has been deprecated in `react` 18.\n\n#### Same test but with React dependency not being a \"singleton\"\n\nThe new `ModuleFederationConfig` config for this test is:\n\n```js\n// host/webpack.dev.js - 8080\n\nnew ModuleFederationPlugin({\n    name: \"host\",\n    remotes: {\n        remote1: \"remote1@http://localhost:8081/remoteEntry.js\",\n        remote2: \"remote2@http://localhost:8082/remoteEntry.js\"\n    },\n    shared: {\n        \"react\": {},\n        \"react-dom\": {},\n        \"shared\": {\n            singleton: true\n        },\n        \"useless-lib\": {}\n    }\n})\n```\n\n```js\n// remote-1/webpack.dev.js - 8081\n\nnew ModuleFederationPlugin({\n    name: \"remote1\",\n    filename: \"remoteEntry.js\",\n    exposes: {\n        \"./HelloWorld.jsx\": \"./src/HelloWorld.jsx\"\n    },\n    shared: {\n        \"react\": {},\n        \"react-dom\": {},\n        \"shared\": {\n            singleton: true\n        },\n        \"useless-lib\": {}\n})\n```\n\n```js\n// remote-2/webpack.dev.js - 8082\n\nnew ModuleFederationPlugin({\n    name: \"remote2\",\n    filename: \"remoteEntry.js\",\n    exposes: {\n        \"./HelloWorld.jsx\": \"./src/HelloWorld.jsx\"\n    },\n    shared: {\n        \"react\": {},\n        \"react-dom\": {},\n        \"shared\": {\n            singleton: true\n        },\n        \"useless-lib\": {}\n    }\n})\n```\n\nSince a \"singleton\" is not requested anymore, when \"remote-1\" is loaded, `react` 17.0.2 is also loaded:\n\n- http://localhost:8081/vendors-node_modules_pnpm_react_17_0_2_node_modules_react_index_js.js\n- http://localhost:8081/vendors-node_modules_pnpm_react_17_0_2_node_modules_react_jsx-runtime_js.js\n\nWhat's actually interesting is that sharing a `React.context` value between the host applications and \"remote-1\" is working. The reason is because the source code of the context is defined in the `shared` package which is defined as a \"singleton\".\n\nHowever, hooks depending on having a single instance of `react`, like the `useState` hook won't work. Adding a `useState` hook to \"remote-1\" throw the following error:\n\n\u003e Invalid hook call. Hooks can only be called inside of the body of a function component\n\n### Using multiple version of react-router in parallel\n\n`react-router` must be defined as a \"singleton\" because it relies on `React.context` which doesn't works otherwise (returns undefined values).\n\nBottomline, the requirements for `react-router` is to be defined as \"singleton\" and that every codebase depends on code that is backward compatible with the highest required version of the package.\n\n### Conclusion\n\n- The default sharing behavior of Webpack Module Federation is quite smart and should be leverage whenever possible. It will only load the highest compatible version when possible, e.g. that if 10.0 and 10.1 are required only 10.1 will be loaded but if 11.0 and 10.1 it will load both because distinct major versions are considered as incompatible\n\n- `react` should always be defined as a \"singleton\", otherwise hooks like `useState` will not work\n\n- `react-router` should always be defined as a \"singleton\" because it depends on `React.context`\n\n- Any package sharing a `React.context` must be defined as \"singleton\", otherwise, values will be null for remotes\n\n- Dependencies required initially should be eagerly loaded by adding `eager: true` in the host application module federation config BUT not in the remote module configuration.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpatricklafrance%2Fwmf-versioning","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpatricklafrance%2Fwmf-versioning","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpatricklafrance%2Fwmf-versioning/lists"}