Skip to content

Commit 5a6a91e

Browse files
authored
feat: add multiple-share-scope example (#4419)
* feat: add multiple-share-scope example * fix: type issue
1 parent 9e45d88 commit 5a6a91e

41 files changed

Lines changed: 5186 additions & 515 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

multiple-share-scope/README.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Module Federation - Multiple Share Scope Example
2+
3+
This example demonstrates how to use **multiple share scopes** in Module Federation to run **React 17** and **React 18** simultaneously in the same host application.
4+
5+
## Architecture
6+
7+
| Application | Port | Description |
8+
| ----------------- | ---- | ------------------------------------------------ |
9+
| `host` | 8080 | Host app consuming both React 17 and React 18 remotes |
10+
| `provider-react-17` | 8081 | Remote exposing components built with React 17 |
11+
| `provider-react-18` | 8082 | Remote exposing components built with React 18 |
12+
13+
## How It Works
14+
15+
The host defines two share scopes:
16+
17+
- **`default`** scope — shares React 17 (`react17` / `react-dom17` aliases)
18+
- **`react18`** scope — shares React 18 (`react` / `react-dom`)
19+
20+
Each remote is associated with the appropriate scope:
21+
22+
- `provider17` uses the `default` scope (React 17)
23+
- `provider18` uses both `['react18', 'default']` scopes (React 18)
24+
25+
This allows isolated React instances per version, preventing version conflicts.
26+
27+
## Running the Demo
28+
29+
Install dependencies:
30+
31+
```bash
32+
pnpm install
33+
```
34+
35+
Start all applications in development mode:
36+
37+
```bash
38+
pnpm start
39+
```
40+
41+
- [localhost:8080](http://localhost:8080/) — Host
42+
- [localhost:8081](http://localhost:8081/) — Provider (React 17)
43+
- [localhost:8082](http://localhost:8082/) — Provider (React 18)
44+
45+
## Build & Preview
46+
47+
```bash
48+
pnpm build
49+
pnpm serve
50+
```
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import type { PackageType as PackageType_0,RemoteKeys as RemoteKeys_0 } from './provider17/apis.d.ts';
2+
import type { PackageType as PackageType_1,RemoteKeys as RemoteKeys_1 } from './provider18/apis.d.ts';
3+
declare module "@module-federation/runtime" {
4+
type RemoteKeys = RemoteKeys_0 | RemoteKeys_1;
5+
type PackageType<T, Y=any> = T extends RemoteKeys_0 ? PackageType_0<T> :
6+
T extends RemoteKeys_1 ? PackageType_1<T> :
7+
Y ;
8+
export function loadRemote<T extends RemoteKeys,Y>(packageName: T): Promise<PackageType<T, Y>>;
9+
export function loadRemote<T extends string,Y>(packageName: T): Promise<PackageType<T, Y>>;
10+
}
11+
declare module "@module-federation/enhanced/runtime" {
12+
type RemoteKeys = RemoteKeys_0 | RemoteKeys_1;
13+
type PackageType<T, Y=any> = T extends RemoteKeys_0 ? PackageType_0<T> :
14+
T extends RemoteKeys_1 ? PackageType_1<T> :
15+
Y ;
16+
export function loadRemote<T extends RemoteKeys,Y>(packageName: T): Promise<PackageType<T, Y>>;
17+
export function loadRemote<T extends string,Y>(packageName: T): Promise<PackageType<T, Y>>;
18+
}
19+
declare module "@module-federation/runtime-tools" {
20+
type RemoteKeys = RemoteKeys_0 | RemoteKeys_1;
21+
type PackageType<T, Y=any> = T extends RemoteKeys_0 ? PackageType_0<T> :
22+
T extends RemoteKeys_1 ? PackageType_1<T> :
23+
Y ;
24+
export function loadRemote<T extends RemoteKeys,Y>(packageName: T): Promise<PackageType<T, Y>>;
25+
export function loadRemote<T extends string,Y>(packageName: T): Promise<PackageType<T, Y>>;
26+
}
27+
declare module "@module-federation/modern-js/runtime" {
28+
type RemoteKeys = RemoteKeys_0 | RemoteKeys_1;
29+
type PackageType<T, Y=any> = T extends RemoteKeys_0 ? PackageType_0<T> :
30+
T extends RemoteKeys_1 ? PackageType_1<T> :
31+
Y ;
32+
export function loadRemote<T extends RemoteKeys,Y>(packageName: T): Promise<PackageType<T, Y>>;
33+
export function loadRemote<T extends string,Y>(packageName: T): Promise<PackageType<T, Y>>;
34+
}
35+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './compiled-types/src/components/LandingPage';
2+
export { default } from './compiled-types/src/components/LandingPage';
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
export type RemoteKeys = 'provider17/LandingPage';
3+
type PackageType<T> = T extends 'provider17/LandingPage' ? typeof import('provider17/LandingPage') :any;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/// <reference types="react" />
2+
declare const LandingPage: (props: any) => JSX.Element;
3+
export default LandingPage;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './compiled-types/src/components/LandingPage';
2+
export { default } from './compiled-types/src/components/LandingPage';
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
export type RemoteKeys = 'provider18/LandingPage';
3+
type PackageType<T> = T extends 'provider18/LandingPage' ? typeof import('provider18/LandingPage') :any;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/// <reference types="react" />
2+
declare const LandingPage: (props: any) => JSX.Element;
3+
export default LandingPage;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { appTools, defineConfig } from '@modern-js/app-tools';
2+
import pluginMF from '@module-federation/modern-js';
3+
4+
export default defineConfig({
5+
runtime: {
6+
router: true,
7+
},
8+
plugins: [
9+
appTools({
10+
bundler: 'webpack', // Set to 'webpack' to enable webpack
11+
}),
12+
pluginMF(),
13+
],
14+
});
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { createModuleFederationConfig } from '@module-federation/modern-js';
2+
3+
export default createModuleFederationConfig({
4+
name: 'host',
5+
remotes: {
6+
provider17: {
7+
external: 'provider17@http://localhost:8081/mf-manifest.json',
8+
},
9+
provider18: {
10+
external: 'provider18@http://localhost:8082/mf-manifest.json',
11+
shareScope: ['react18', 'default'],
12+
},
13+
},
14+
shared: {
15+
react: {
16+
singleton: true,
17+
shareScope: 'react18',
18+
},
19+
'react-dom': {
20+
singleton: true,
21+
shareScope: 'react18',
22+
},
23+
react17: {
24+
shareKey: 'react',
25+
// @ts-ignore wait fix types
26+
request: 'react17',
27+
shareScope: 'default',
28+
singleton: true,
29+
},
30+
'react-dom17': {
31+
shareKey: 'react-dom',
32+
request: 'react-dom17',
33+
shareScope: 'default',
34+
singleton: true,
35+
},
36+
},
37+
});

0 commit comments

Comments
 (0)