Skip to content

Commit 02ce049

Browse files
committed
chore(react): export createRemoteComponent and related react utils
1 parent a40d744 commit 02ce049

Some content is hidden

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

51 files changed

+2782
-618
lines changed

.changeset/config.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
"@module-federation/inject-external-runtime-core-plugin",
2828
"@module-federation/runtime-core",
2929
"create-module-federation",
30-
"@module-federation/cli"
30+
"@module-federation/cli",
31+
"@module-federation/react"
3132
]
3233
],
3334
"ignorePatterns": ["^alpha|^beta"],

.changeset/spicy-parents-greet.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@module-federation/react': patch
3+
'@module-federation/modern-js': patch
4+
---
5+
6+
chore(react): export createRemoteComponent and related react utils

apps/modern-component-data-fetch/provider-csr/module-federation.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createModuleFederationConfig } from '@module-federation/modern-js';
1+
import { createModuleFederationConfig } from '@module-federation/rsbuild-plugin';
22

33
export default createModuleFederationConfig({
44
name: 'provider_csr',

packages/bridge/bridge-react/package.json

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
"url": "https://github.com/module-federation/core",
1212
"directory": "packages/bridge-react"
1313
},
14-
"type": "module",
1514
"main": "./dist/index.cjs.js",
1615
"module": "./dist/index.es.js",
1716
"types": "./dist/index.d.ts",
@@ -32,27 +31,76 @@
3231
"require": "./dist/v19.cjs.js"
3332
},
3433
"./router": {
35-
"types": "./dist/router.d.ts",
34+
"types": "./dist/router/default.d.ts",
3635
"import": "./dist/router.es.js",
3736
"require": "./dist/router.cjs.js"
3837
},
3938
"./plugin": {
40-
"types": "./dist/plugin.d.ts",
39+
"types": "./dist/provider/plugin.d.ts",
4140
"import": "./dist/plugin.es.js",
4241
"require": "./dist/plugin.es.js"
4342
},
4443
"./router-v5": {
45-
"types": "./dist/router-v5.d.ts",
44+
"types": "./dist/router/v5.d.ts",
4645
"import": "./dist/router-v5.es.js",
4746
"require": "./dist/router-v5.cjs.js"
4847
},
4948
"./router-v6": {
50-
"types": "./dist/router-v6.d.ts",
49+
"types": "./dist/router/v6.d.ts",
5150
"import": "./dist/router-v6.es.js",
5251
"require": "./dist/router-v6.cjs.js"
5352
},
53+
"./data-fetch-runtime-plugin": {
54+
"types": "./dist/module/data-fetch/runtime-plugin.d.ts",
55+
"import": "./dist/data-fetch-runtime-plugin.es.js",
56+
"require": "./dist/data-fetch-runtime-plugin.cjs.js"
57+
},
58+
"./data-fetch-utils": {
59+
"types": "./dist/module/utils.d.ts",
60+
"import": "./dist/data-fetch-utils.es.js",
61+
"require": "./dist/data-fetch-utils.cjs.js"
62+
},
63+
"./data-fetch-server-middleware": {
64+
"types": "./dist/module/data-fetch/data-fetch-server-middleware.d.ts",
65+
"import": "./dist/data-fetch-server-middleware.es.js",
66+
"require": "./dist/data-fetch-server-middleware.cjs.js"
67+
},
5468
"./*": "./*"
5569
},
70+
"typesVersions": {
71+
"*": {
72+
".": [
73+
"./dist/index.d.ts"
74+
],
75+
"v18": [
76+
"./dist/v18.d.ts"
77+
],
78+
"v19": [
79+
"./dist/v19.d.ts"
80+
],
81+
"router": [
82+
"./dist/router/default.d.ts"
83+
],
84+
"plugin": [
85+
"./dist/provider/plugin.d.ts"
86+
],
87+
"router-v5": [
88+
"./dist/router/v5.d.ts"
89+
],
90+
"router-v6": [
91+
"./dist/router/v6.d.ts"
92+
],
93+
"data-fetch-runtime-plugin": [
94+
"./dist/module/data-fetch/runtime-plugin.d.ts"
95+
],
96+
"data-fetch-utils": [
97+
"./dist/module/utils.d.ts"
98+
],
99+
"data-fetch-server-middleware": [
100+
"./dist/module/data-fetch/data-fetch-server-middleware.d.ts"
101+
]
102+
}
103+
},
56104
"scripts": {
57105
"dev": "vite",
58106
"build": "vite build",
@@ -81,7 +129,8 @@
81129
"react-router-dom": "6.22.3",
82130
"typescript": "^5.2.2",
83131
"vite": "^5.4.18",
84-
"vite-plugin-dts": "^4.3.0",
85-
"@module-federation/runtime": "workspace:*"
132+
"vite-plugin-dts": "^4.5.4",
133+
"@module-federation/runtime": "workspace:*",
134+
"hono": "3.12.12"
86135
}
87136
}

packages/bridge/bridge-react/src/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,11 @@ export type {
1212
DestroyParams,
1313
RenderParams,
1414
} from './types';
15+
16+
export { kit, ERROR_TYPE, autoFetchDataPlugin } from './module';
17+
export type {
18+
DataFetchParams,
19+
NoSSRRemoteInfo,
20+
CollectSSRAssetsOptions,
21+
CreateRemoteComponentOptions,
22+
} from './module';

packages/modernjs/src/runtime/AwaitDataFetch.tsx renamed to packages/bridge/bridge-react/src/module/AwaitDataFetch.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import React, { MutableRefObject, ReactNode, Suspense, useRef } from 'react';
2-
import logger from '../logger';
2+
import logger from './logger';
33
import {
44
DATA_FETCH_ERROR_PREFIX,
55
LOAD_REMOTE_ERROR_PREFIX,
66
ERROR_TYPE,
7-
DOWNGRADE_KEY,
87
DATA_FETCH_FUNCTION,
9-
} from '../constant';
10-
import { getDataFetchIdWithErrorMsgs, wrapDataFetchId } from '../utils';
11-
import type { DataFetchParams } from '../interfaces/global';
8+
} from './constant';
9+
10+
import { getDataFetchIdWithErrorMsgs, wrapDataFetchId } from './utils';
11+
import type { DataFetchParams } from './types';
1212

1313
function isPromise<T>(obj: any): obj is PromiseLike<T> {
1414
return (
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
export const PLUGIN_IDENTIFIER = '[ Module Federation React ]';
2+
export const DOWNGRADE_KEY = '_mfSSRDowngrade';
3+
export const DATA_FETCH_MAP_KEY = '__MF_DATA_FETCH_MAP__';
4+
export const DATA_FETCH_FUNCTION = '_mfDataFetch';
5+
export const FS_HREF = '_mfFSHref';
6+
export const ERROR_TYPE = {
7+
DATA_FETCH: 1,
8+
LOAD_REMOTE: 2,
9+
UNKNOWN: 3,
10+
};
11+
export const WRAP_DATA_FETCH_ID_IDENTIFIER = 'wrap_dfip_identifier';
12+
export const enum MF_DATA_FETCH_TYPE {
13+
FETCH_SERVER = 1,
14+
FETCH_CLIENT = 2,
15+
}
16+
17+
export const enum MF_DATA_FETCH_STATUS {
18+
LOADED = 1,
19+
LOADING = 2,
20+
AWAIT = 0,
21+
ERROR = 3,
22+
}
23+
24+
export const DATA_FETCH_IDENTIFIER = 'data';
25+
export const DATA_FETCH_CLIENT_SUFFIX = '.client';
26+
export const DATA_FETCH_QUERY = 'x-mf-data-fetch';
27+
export const DATA_FETCH_ERROR_PREFIX =
28+
'caught the following error during dataFetch: ';
29+
export const LOAD_REMOTE_ERROR_PREFIX =
30+
'caught the following error during loadRemote: ';

packages/modernjs/src/runtime/createRemoteComponent.tsx renamed to packages/bridge/bridge-react/src/module/createRemoteComponent.tsx

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,32 @@
11
import React, { ReactNode, useEffect, useState } from 'react';
2-
import logger from '../logger';
3-
import { getInstance } from '@module-federation/enhanced/runtime';
2+
import logger from './logger';
43
import { AwaitDataFetch, transformError } from './AwaitDataFetch';
54
import {
65
fetchData,
76
getDataFetchItem,
87
getDataFetchMapKey,
9-
} from '../utils/dataFetch';
10-
import {
118
getDataFetchInfo,
129
getLoadedRemoteInfos,
1310
setDataFetchItemLoadedStatus,
1411
wrapDataFetchId,
15-
} from '../utils';
12+
} from './utils';
1613
import {
1714
DATA_FETCH_ERROR_PREFIX,
1815
DATA_FETCH_FUNCTION,
1916
FS_HREF,
2017
LOAD_REMOTE_ERROR_PREFIX,
2118
MF_DATA_FETCH_TYPE,
22-
} from '../constant';
19+
} from './constant';
20+
2321
import type { ErrorInfo } from './AwaitDataFetch';
24-
import type { DataFetchParams, NoSSRRemoteInfo } from '../interfaces/global';
22+
import type { DataFetchParams, NoSSRRemoteInfo } from './types';
23+
import type { FederationHost } from '@module-federation/runtime';
2524

26-
type IProps = {
25+
export type IProps = {
2726
id: string;
2827
injectScript?: boolean;
2928
injectLink?: boolean;
29+
runtime: typeof import('@module-federation/runtime');
3030
};
3131

3232
export type CreateRemoteComponentOptions<T, E extends keyof T> = {
@@ -36,12 +36,12 @@ export type CreateRemoteComponentOptions<T, E extends keyof T> = {
3636
export?: E;
3737
dataFetchParams?: DataFetchParams;
3838
noSSR?: boolean;
39+
runtime: typeof import('@module-federation/runtime');
3940
};
4041

4142
type ReactKey = { key?: React.Key | null };
4243

43-
function getTargetModuleInfo(id: string) {
44-
const instance = getInstance();
44+
function getTargetModuleInfo(id: string, instance?: FederationHost) {
4545
if (!instance) {
4646
return;
4747
}
@@ -89,12 +89,12 @@ export function collectSSRAssets(options: IProps) {
8989
} = typeof options === 'string' ? { id: options } : options;
9090
const links: React.ReactNode[] = [];
9191
const scripts: React.ReactNode[] = [];
92-
const instance = getInstance();
92+
const instance = options.runtime.getInstance();
9393
if (!instance || (!injectLink && !injectScript)) {
9494
return [...scripts, ...links];
9595
}
9696

97-
const moduleAndPublicPath = getTargetModuleInfo(id);
97+
const moduleAndPublicPath = getTargetModuleInfo(id, instance);
9898
if (!moduleAndPublicPath) {
9999
return [...scripts, ...links];
100100
}
@@ -192,6 +192,12 @@ function getServerNeedRemoteInfo(
192192
export function createRemoteComponent<T, E extends keyof T>(
193193
options: CreateRemoteComponentOptions<T, E>,
194194
) {
195+
const { runtime } = options;
196+
if (!runtime?.getInstance) {
197+
throw new Error(
198+
'runtime is required if used in "@module-federation/bridge-react"!',
199+
);
200+
}
195201
type ComponentType = T[E] extends (...args: any) => any
196202
? Parameters<T[E]>[0] extends undefined
197203
? ReactKey
@@ -213,7 +219,7 @@ export function createRemoteComponent<T, E extends keyof T>(
213219
const getData = async (noSSR?: boolean) => {
214220
let loadedRemoteInfo: ReturnType<typeof getLoadedRemoteInfos>;
215221
let moduleId: string;
216-
const instance = getInstance();
222+
const instance = runtime.getInstance();
217223
try {
218224
const m = await callLoader();
219225
moduleId = m && m[Symbol.for('mf_module_id')];
@@ -265,7 +271,7 @@ export function createRemoteComponent<T, E extends keyof T>(
265271
const LazyComponent = React.lazy(async () => {
266272
const m = await callLoader();
267273
const moduleId = m && m[Symbol.for('mf_module_id')];
268-
const instance = getInstance()!;
274+
const instance = runtime.getInstance()!;
269275
const loadedRemoteInfo = getLoadedRemoteInfos(moduleId, instance);
270276
loadedRemoteInfo?.snapshot;
271277
const dataFetchMapKey = loadedRemoteInfo
@@ -283,6 +289,7 @@ export function createRemoteComponent<T, E extends keyof T>(
283289

284290
const assets = collectSSRAssets({
285291
id: moduleId,
292+
runtime,
286293
});
287294

288295
const Com = m[exportName] as React.FC<ComponentType>;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { DATA_FETCH_FUNCTION } from '../constant';
2+
import { dataFetchFunction } from './inject-data-fetch';
3+
4+
export async function callDataFetch() {
5+
const dataFetch = globalThis[DATA_FETCH_FUNCTION];
6+
if (dataFetch) {
7+
await Promise.all(
8+
dataFetch.map(async (options) => {
9+
await dataFetchFunction(options);
10+
}),
11+
);
12+
}
13+
}

0 commit comments

Comments
 (0)