@module-federation/data-prefetch 0.0.0-next-20240617071542 → 0.0.0-next-20240701101956
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -5
- package/README.md +1 -2
- package/__tests__/babel.spec.ts +75 -0
- package/__tests__/prefetch.spec.ts +127 -0
- package/__tests__/react.spec.ts +109 -0
- package/dist/cli/index.js +17 -36
- package/dist/esm/{chunk-BN3GGCE5.js → chunk-VJO2H3UO.js} +30 -14
- package/dist/esm/cli/index.js +18 -38
- package/dist/esm/index.js +1 -1
- package/dist/esm/plugin.js +1 -1
- package/dist/esm/react/index.js +2 -2
- package/dist/esm/shared/index.js +25 -0
- package/dist/index.js +30 -14
- package/dist/plugin.js +30 -14
- package/dist/react/index.js +2 -2
- package/dist/shared/index.d.ts +5 -0
- package/dist/shared/index.js +48 -0
- package/package.json +11 -3
- package/src/cli/babel.ts +93 -0
- package/src/cli/index.ts +98 -0
- package/src/common/constant.ts +1 -0
- package/src/common/index.ts +1 -0
- package/src/common/node-utils.ts +24 -0
- package/src/common/runtime-utils.ts +35 -0
- package/src/index.ts +2 -0
- package/src/logger/index.ts +3 -0
- package/src/plugin.ts +190 -0
- package/src/prefetch.ts +210 -0
- package/src/react/hooks.ts +95 -0
- package/src/react/index.ts +1 -0
- package/src/react/utils.ts +11 -0
- package/src/shared/index.ts +26 -0
- package/src/universal/index.ts +27 -0
- package/tsup.config.ts +35 -0
package/dist/index.js
CHANGED
|
@@ -200,9 +200,11 @@ var logger_default = new import_sdk3.Logger("[Module Federation Data Prefetch]")
|
|
|
200
200
|
|
|
201
201
|
// src/plugin.ts
|
|
202
202
|
var loadingArray = [];
|
|
203
|
+
var strategy = "loaded-first";
|
|
204
|
+
var sharedFlag = strategy;
|
|
203
205
|
var prefetchPlugin = () => ({
|
|
204
206
|
name: "data-prefetch-runtime-plugin",
|
|
205
|
-
|
|
207
|
+
initContainer(options) {
|
|
206
208
|
const { remoteSnapshot, remoteInfo, id, origin } = options;
|
|
207
209
|
const snapshot = remoteSnapshot;
|
|
208
210
|
const { name } = remoteInfo;
|
|
@@ -216,6 +218,11 @@ var prefetchPlugin = () => ({
|
|
|
216
218
|
if (!signal) {
|
|
217
219
|
return options;
|
|
218
220
|
}
|
|
221
|
+
if (sharedFlag !== strategy) {
|
|
222
|
+
throw new Error(
|
|
223
|
+
`[Module Federation Data Prefetch]: If you want to use data prefetch, the shared strategy must be 'loaded-first'`
|
|
224
|
+
);
|
|
225
|
+
}
|
|
219
226
|
const instance = MFDataPrefetch.getInstance(name) || new MFDataPrefetch(prefetchOptions);
|
|
220
227
|
let prefetchUrl;
|
|
221
228
|
if (snapshot.prefetchEntry) {
|
|
@@ -230,20 +237,22 @@ var prefetchPlugin = () => ({
|
|
|
230
237
|
if (projectExports instanceof Promise) {
|
|
231
238
|
await projectExports;
|
|
232
239
|
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
|
|
240
|
+
return Promise.resolve().then(() => {
|
|
241
|
+
const exports = instance.getExposeExports(id);
|
|
242
|
+
logger_default.info(`1. Start Prefetch: ${id} - ${performance.now()}`);
|
|
243
|
+
const result = Object.keys(exports).map((k) => {
|
|
244
|
+
const value = instance.prefetch({
|
|
245
|
+
id,
|
|
246
|
+
functionId: k
|
|
247
|
+
});
|
|
248
|
+
const functionId = k;
|
|
249
|
+
return {
|
|
250
|
+
value,
|
|
251
|
+
functionId
|
|
252
|
+
};
|
|
239
253
|
});
|
|
240
|
-
|
|
241
|
-
return {
|
|
242
|
-
value,
|
|
243
|
-
functionId
|
|
244
|
-
};
|
|
254
|
+
return result;
|
|
245
255
|
});
|
|
246
|
-
return result;
|
|
247
256
|
});
|
|
248
257
|
loadingArray.push({
|
|
249
258
|
id,
|
|
@@ -296,7 +305,9 @@ var prefetchPlugin = () => ({
|
|
|
296
305
|
await projectExports;
|
|
297
306
|
}
|
|
298
307
|
const exports = instance.getExposeExports(id);
|
|
299
|
-
logger_default.info(
|
|
308
|
+
logger_default.info(
|
|
309
|
+
`1. PreloadRemote Start Prefetch: ${id} - ${performance.now()}`
|
|
310
|
+
);
|
|
300
311
|
const result = Object.keys(exports).map((k) => {
|
|
301
312
|
const value = instance.prefetch({
|
|
302
313
|
id,
|
|
@@ -315,6 +326,11 @@ var prefetchPlugin = () => ({
|
|
|
315
326
|
promise
|
|
316
327
|
});
|
|
317
328
|
return options;
|
|
329
|
+
},
|
|
330
|
+
beforeLoadShare(options) {
|
|
331
|
+
const shareInfo = options.shareInfo;
|
|
332
|
+
sharedFlag = (shareInfo == null ? void 0 : shareInfo.strategy) || sharedFlag;
|
|
333
|
+
return options;
|
|
318
334
|
}
|
|
319
335
|
});
|
|
320
336
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/plugin.js
CHANGED
|
@@ -196,9 +196,11 @@ var logger_default = new import_sdk3.Logger("[Module Federation Data Prefetch]")
|
|
|
196
196
|
|
|
197
197
|
// src/plugin.ts
|
|
198
198
|
var loadingArray = [];
|
|
199
|
+
var strategy = "loaded-first";
|
|
200
|
+
var sharedFlag = strategy;
|
|
199
201
|
var prefetchPlugin = () => ({
|
|
200
202
|
name: "data-prefetch-runtime-plugin",
|
|
201
|
-
|
|
203
|
+
initContainer(options) {
|
|
202
204
|
const { remoteSnapshot, remoteInfo, id, origin } = options;
|
|
203
205
|
const snapshot = remoteSnapshot;
|
|
204
206
|
const { name } = remoteInfo;
|
|
@@ -212,6 +214,11 @@ var prefetchPlugin = () => ({
|
|
|
212
214
|
if (!signal) {
|
|
213
215
|
return options;
|
|
214
216
|
}
|
|
217
|
+
if (sharedFlag !== strategy) {
|
|
218
|
+
throw new Error(
|
|
219
|
+
`[Module Federation Data Prefetch]: If you want to use data prefetch, the shared strategy must be 'loaded-first'`
|
|
220
|
+
);
|
|
221
|
+
}
|
|
215
222
|
const instance = MFDataPrefetch.getInstance(name) || new MFDataPrefetch(prefetchOptions);
|
|
216
223
|
let prefetchUrl;
|
|
217
224
|
if (snapshot.prefetchEntry) {
|
|
@@ -226,20 +233,22 @@ var prefetchPlugin = () => ({
|
|
|
226
233
|
if (projectExports instanceof Promise) {
|
|
227
234
|
await projectExports;
|
|
228
235
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
const
|
|
233
|
-
|
|
234
|
-
|
|
236
|
+
return Promise.resolve().then(() => {
|
|
237
|
+
const exports = instance.getExposeExports(id);
|
|
238
|
+
logger_default.info(`1. Start Prefetch: ${id} - ${performance.now()}`);
|
|
239
|
+
const result = Object.keys(exports).map((k) => {
|
|
240
|
+
const value = instance.prefetch({
|
|
241
|
+
id,
|
|
242
|
+
functionId: k
|
|
243
|
+
});
|
|
244
|
+
const functionId = k;
|
|
245
|
+
return {
|
|
246
|
+
value,
|
|
247
|
+
functionId
|
|
248
|
+
};
|
|
235
249
|
});
|
|
236
|
-
|
|
237
|
-
return {
|
|
238
|
-
value,
|
|
239
|
-
functionId
|
|
240
|
-
};
|
|
250
|
+
return result;
|
|
241
251
|
});
|
|
242
|
-
return result;
|
|
243
252
|
});
|
|
244
253
|
loadingArray.push({
|
|
245
254
|
id,
|
|
@@ -292,7 +301,9 @@ var prefetchPlugin = () => ({
|
|
|
292
301
|
await projectExports;
|
|
293
302
|
}
|
|
294
303
|
const exports = instance.getExposeExports(id);
|
|
295
|
-
logger_default.info(
|
|
304
|
+
logger_default.info(
|
|
305
|
+
`1. PreloadRemote Start Prefetch: ${id} - ${performance.now()}`
|
|
306
|
+
);
|
|
296
307
|
const result = Object.keys(exports).map((k) => {
|
|
297
308
|
const value = instance.prefetch({
|
|
298
309
|
id,
|
|
@@ -311,6 +322,11 @@ var prefetchPlugin = () => ({
|
|
|
311
322
|
promise
|
|
312
323
|
});
|
|
313
324
|
return options;
|
|
325
|
+
},
|
|
326
|
+
beforeLoadShare(options) {
|
|
327
|
+
const shareInfo = options.shareInfo;
|
|
328
|
+
sharedFlag = (shareInfo == null ? void 0 : shareInfo.strategy) || sharedFlag;
|
|
329
|
+
return options;
|
|
314
330
|
}
|
|
315
331
|
});
|
|
316
332
|
var plugin_default = prefetchPlugin;
|
package/dist/react/index.js
CHANGED
|
@@ -231,7 +231,7 @@ var usePrefetch = (options) => {
|
|
|
231
231
|
if (isFirstMounted) {
|
|
232
232
|
const startTiming = performance.now();
|
|
233
233
|
logger_default.info(
|
|
234
|
-
`2. Start Get Prefetch Data: ${options.id} - ${options.functionId} - ${startTiming}`
|
|
234
|
+
`2. Start Get Prefetch Data: ${options.id} - ${options.functionId || "default"} - ${startTiming}`
|
|
235
235
|
);
|
|
236
236
|
}
|
|
237
237
|
const { id, functionId, deferId } = options;
|
|
@@ -260,7 +260,7 @@ var usePrefetch = (options) => {
|
|
|
260
260
|
(0, import_react2.useEffect)(() => {
|
|
261
261
|
const useEffectTiming = performance.now();
|
|
262
262
|
logger_default.info(
|
|
263
|
-
`3. Start Execute UseEffect: ${options.id} - ${options.functionId} - ${useEffectTiming}`
|
|
263
|
+
`3. Start Execute UseEffect: ${options.id} - ${options.functionId || "default"} - ${useEffectTiming}`
|
|
264
264
|
);
|
|
265
265
|
return () => {
|
|
266
266
|
prefetchInstance == null ? void 0 : prefetchInstance.markOutdate(prefetchInfo, true);
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/shared/index.ts
|
|
21
|
+
var shared_exports = {};
|
|
22
|
+
__export(shared_exports, {
|
|
23
|
+
default: () => shared_default
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(shared_exports);
|
|
26
|
+
var sharedStrategy = () => ({
|
|
27
|
+
name: "shared-strategy",
|
|
28
|
+
beforeInit(args) {
|
|
29
|
+
const { userOptions } = args;
|
|
30
|
+
const shared = userOptions.shared;
|
|
31
|
+
if (shared) {
|
|
32
|
+
Object.keys(shared).forEach((sharedKey) => {
|
|
33
|
+
const sharedConfigs = shared[sharedKey];
|
|
34
|
+
const arraySharedConfigs = Array.isArray(sharedConfigs) ? sharedConfigs : [sharedConfigs];
|
|
35
|
+
arraySharedConfigs.forEach((s) => {
|
|
36
|
+
s.strategy = "loaded-first";
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
console.warn(
|
|
40
|
+
`[Module Federation Data Prefetch]: Your shared strategy is set to 'loaded-first', this is a necessary condition for data prefetch`
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
return args;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
var shared_default = sharedStrategy;
|
|
47
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
48
|
+
0 && (module.exports = {});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@module-federation/data-prefetch",
|
|
3
3
|
"description": "Module Federation Data Prefetch",
|
|
4
|
-
"version": "0.0.0-next-
|
|
4
|
+
"version": "0.0.0-next-20240701101956",
|
|
5
5
|
"author": "nieyan <nyqykk@foxmail.com>",
|
|
6
6
|
"homepage": "https://github.com/module-federation/core",
|
|
7
7
|
"license": "MIT",
|
|
@@ -33,6 +33,11 @@
|
|
|
33
33
|
"import": "./dist/esm/universal/index.js",
|
|
34
34
|
"require": "./dist/universal/index.js",
|
|
35
35
|
"types": "./dist/universal/index.d.ts"
|
|
36
|
+
},
|
|
37
|
+
"./shared": {
|
|
38
|
+
"import": "./dist/esm/shared/index.js",
|
|
39
|
+
"require": "./dist/shared/index.js",
|
|
40
|
+
"types": "./dist/shared/index.d.ts"
|
|
36
41
|
}
|
|
37
42
|
},
|
|
38
43
|
"typesVersions": {
|
|
@@ -48,6 +53,9 @@
|
|
|
48
53
|
],
|
|
49
54
|
"universal": [
|
|
50
55
|
"./dist/universal/index.d.ts"
|
|
56
|
+
],
|
|
57
|
+
"shared": [
|
|
58
|
+
"./dist/shared/index.d.ts"
|
|
51
59
|
]
|
|
52
60
|
}
|
|
53
61
|
},
|
|
@@ -77,8 +85,8 @@
|
|
|
77
85
|
},
|
|
78
86
|
"dependencies": {
|
|
79
87
|
"fs-extra": "9.1.0",
|
|
80
|
-
"@module-federation/sdk": "0.0.0-next-
|
|
81
|
-
"@module-federation/runtime": "0.0.0-next-
|
|
88
|
+
"@module-federation/sdk": "0.0.0-next-20240701101956",
|
|
89
|
+
"@module-federation/runtime": "0.0.0-next-20240701101956"
|
|
82
90
|
},
|
|
83
91
|
"scripts": {
|
|
84
92
|
"dev": "cross-env WATCH=true tsup",
|
package/src/cli/babel.ts
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import type { moduleFederationPlugin } from '@module-federation/sdk';
|
|
3
|
+
|
|
4
|
+
const attribute = 'id';
|
|
5
|
+
const hookId = 'usePrefetch';
|
|
6
|
+
const importPackage = '@module-federation/data-prefetch/react';
|
|
7
|
+
|
|
8
|
+
interface BabelPluginOptions {
|
|
9
|
+
hook_id: string;
|
|
10
|
+
import_pkg: string;
|
|
11
|
+
attribute: string;
|
|
12
|
+
mf_name: string;
|
|
13
|
+
exposes: moduleFederationPlugin.ModuleFederationPluginOptions['exposes'];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
17
|
+
export default (babel: { types: any }, options: BabelPluginOptions) => {
|
|
18
|
+
const t = babel.types;
|
|
19
|
+
let shouldHandle = false;
|
|
20
|
+
let scope = '';
|
|
21
|
+
const { mf_name: name, exposes } = options;
|
|
22
|
+
if (!exposes) {
|
|
23
|
+
return {};
|
|
24
|
+
}
|
|
25
|
+
const exposesKey = Object.keys(exposes);
|
|
26
|
+
const processedExposes = exposesKey.map((expose) => ({
|
|
27
|
+
key: expose.replace('.', ''),
|
|
28
|
+
value: path.resolve(
|
|
29
|
+
// @ts-ignore
|
|
30
|
+
typeof exposes[expose] === 'string'
|
|
31
|
+
? // @ts-ignore
|
|
32
|
+
exposes[expose]
|
|
33
|
+
: // @ts-ignore
|
|
34
|
+
exposes[expose].import,
|
|
35
|
+
),
|
|
36
|
+
}));
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
visitor: {
|
|
40
|
+
ImportDeclaration(
|
|
41
|
+
nodePath: {
|
|
42
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
43
|
+
node: { source: { value: any }; specifiers: any };
|
|
44
|
+
},
|
|
45
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
46
|
+
state: { file: { opts: { filename: any } } },
|
|
47
|
+
) {
|
|
48
|
+
const source = nodePath.node.source.value;
|
|
49
|
+
const { specifiers } = nodePath.node;
|
|
50
|
+
const { filename } = state.file.opts;
|
|
51
|
+
|
|
52
|
+
if (source === importPackage) {
|
|
53
|
+
shouldHandle = specifiers.some(
|
|
54
|
+
(specifier: { imported: { name: string } }) =>
|
|
55
|
+
specifier.imported &&
|
|
56
|
+
specifier.imported.name === hookId &&
|
|
57
|
+
processedExposes.find(
|
|
58
|
+
// biome-ignore lint/suspicious/noAssignInExpressions: <explanation>
|
|
59
|
+
(expose) => expose.value === filename && (scope = expose.key),
|
|
60
|
+
),
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
CallExpression(nodePath: {
|
|
66
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
67
|
+
node: { callee: any; arguments: string | any[] };
|
|
68
|
+
}) {
|
|
69
|
+
if (
|
|
70
|
+
shouldHandle &&
|
|
71
|
+
t.isIdentifier(nodePath.node.callee, { name: hookId }) &&
|
|
72
|
+
nodePath.node.arguments.length > 0
|
|
73
|
+
) {
|
|
74
|
+
const objectExpression = nodePath.node.arguments[0];
|
|
75
|
+
if (
|
|
76
|
+
objectExpression &&
|
|
77
|
+
t.isObjectExpression(objectExpression) &&
|
|
78
|
+
!objectExpression.properties.find(
|
|
79
|
+
(p: { key: { name: string } }) => p.key.name === attribute,
|
|
80
|
+
)
|
|
81
|
+
) {
|
|
82
|
+
objectExpression.properties.push(
|
|
83
|
+
t.objectProperty(
|
|
84
|
+
t.identifier(attribute),
|
|
85
|
+
t.stringLiteral(name + scope),
|
|
86
|
+
),
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
};
|
package/src/cli/index.ts
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
encodeName,
|
|
6
|
+
moduleFederationPlugin,
|
|
7
|
+
MFPrefetchCommon,
|
|
8
|
+
} from '@module-federation/sdk';
|
|
9
|
+
import type { Compiler, WebpackPluginInstance } from 'webpack';
|
|
10
|
+
|
|
11
|
+
import { TEMP_DIR } from '../common/constant';
|
|
12
|
+
import { fileExistsWithCaseSync, fixPrefetchPath } from '../common/node-utils';
|
|
13
|
+
import { getPrefetchId } from '../common/runtime-utils';
|
|
14
|
+
|
|
15
|
+
export class PrefetchPlugin implements WebpackPluginInstance {
|
|
16
|
+
public options: moduleFederationPlugin.ModuleFederationPluginOptions;
|
|
17
|
+
private _reWriteExports: string;
|
|
18
|
+
|
|
19
|
+
constructor(options: moduleFederationPlugin.ModuleFederationPluginOptions) {
|
|
20
|
+
this.options = options;
|
|
21
|
+
this._reWriteExports = '';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// eslint-disable-next-line max-lines-per-function
|
|
25
|
+
apply(compiler: Compiler) {
|
|
26
|
+
const { name, exposes } = this.options;
|
|
27
|
+
if (!exposes) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (!compiler.options.context) {
|
|
31
|
+
throw new Error('compiler.options.context is not defined');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const { runtimePlugins } = this.options;
|
|
35
|
+
if (!Array.isArray(runtimePlugins)) {
|
|
36
|
+
this.options.runtimePlugins = [];
|
|
37
|
+
}
|
|
38
|
+
this.options.runtimePlugins!.push(
|
|
39
|
+
path.resolve(__dirname, '../esm/plugin.js'),
|
|
40
|
+
);
|
|
41
|
+
this.options.runtimePlugins!.push(
|
|
42
|
+
path.resolve(__dirname, '../esm/shared/index.js'),
|
|
43
|
+
);
|
|
44
|
+
if (!this.options.dataPrefetch) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const prefetchs: Array<string> = [];
|
|
49
|
+
const exposeAlias = Object.keys(exposes);
|
|
50
|
+
exposeAlias.forEach((alias) => {
|
|
51
|
+
let exposePath;
|
|
52
|
+
// @ts-ignore
|
|
53
|
+
const exposeValue = exposes[alias];
|
|
54
|
+
if (typeof exposeValue === 'string') {
|
|
55
|
+
exposePath = exposeValue;
|
|
56
|
+
} else {
|
|
57
|
+
exposePath = exposeValue.import[0];
|
|
58
|
+
}
|
|
59
|
+
const targetPaths = fixPrefetchPath(exposePath);
|
|
60
|
+
for (const pathItem of targetPaths) {
|
|
61
|
+
const absolutePath = path.resolve(compiler.options.context!, pathItem);
|
|
62
|
+
if (fileExistsWithCaseSync(absolutePath)) {
|
|
63
|
+
prefetchs.push(pathItem);
|
|
64
|
+
const absoluteAlias = alias.replace('.', '');
|
|
65
|
+
this._reWriteExports += `export * as ${getPrefetchId(
|
|
66
|
+
`${name}${absoluteAlias}`,
|
|
67
|
+
)} from '${absolutePath}';\n`;
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
if (!this._reWriteExports) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const encodedName = encodeName(name as string);
|
|
78
|
+
const asyncEntryPath = path.resolve(
|
|
79
|
+
compiler.options.context,
|
|
80
|
+
`node_modules/${TEMP_DIR}/${encodedName}/bootstrap.js`,
|
|
81
|
+
);
|
|
82
|
+
const tempDirRealPath = path.resolve(
|
|
83
|
+
compiler.options.context,
|
|
84
|
+
'node_modules',
|
|
85
|
+
TEMP_DIR,
|
|
86
|
+
);
|
|
87
|
+
if (!fs.existsSync(tempDirRealPath)) {
|
|
88
|
+
fs.mkdirSync(tempDirRealPath);
|
|
89
|
+
}
|
|
90
|
+
if (!fs.existsSync(`${tempDirRealPath}/${encodedName}`)) {
|
|
91
|
+
fs.mkdirSync(`${tempDirRealPath}/${encodedName}`);
|
|
92
|
+
}
|
|
93
|
+
fs.writeFileSync(asyncEntryPath, this._reWriteExports);
|
|
94
|
+
new compiler.webpack.DefinePlugin({
|
|
95
|
+
FederationDataPrefetch: JSON.stringify(asyncEntryPath),
|
|
96
|
+
}).apply(compiler);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const TEMP_DIR = '.mf';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './constant';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
|
|
4
|
+
export const fileExistsWithCaseSync = (filepath: string): boolean => {
|
|
5
|
+
const dir = path.dirname(filepath);
|
|
6
|
+
if (filepath === '/' || filepath === '.') {
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
const filenames = fs.readdirSync(dir);
|
|
10
|
+
if (filenames.indexOf(path.basename(filepath)) === -1) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
return fileExistsWithCaseSync(dir);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const fixPrefetchPath = (exposePath: string): Array<string> => {
|
|
17
|
+
const pathExt = ['.js', '.ts'];
|
|
18
|
+
const extReg = /\.(ts|js|tsx|jsx)$/;
|
|
19
|
+
if (extReg.test(exposePath)) {
|
|
20
|
+
return pathExt.map((ext) => exposePath.replace(extReg, `.prefetch${ext}`));
|
|
21
|
+
} else {
|
|
22
|
+
return pathExt.map((ext) => exposePath + `.prefetch${ext}`);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {
|
|
2
|
+
encodeName,
|
|
3
|
+
ModuleInfo,
|
|
4
|
+
MFPrefetchCommon,
|
|
5
|
+
} from '@module-federation/sdk';
|
|
6
|
+
|
|
7
|
+
export const getScope = (id: string): string => {
|
|
8
|
+
const idArray = id.split('/');
|
|
9
|
+
if (idArray.length >= 2) {
|
|
10
|
+
idArray.pop();
|
|
11
|
+
}
|
|
12
|
+
const name = idArray.join('/');
|
|
13
|
+
return name;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const getPrefetchId = (id: string): string =>
|
|
17
|
+
encodeName(`${id}/${MFPrefetchCommon.identifier}`);
|
|
18
|
+
|
|
19
|
+
export const getSignalFromManifest = (remoteSnapshot: ModuleInfo): boolean => {
|
|
20
|
+
if (!remoteSnapshot) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (
|
|
25
|
+
!('prefetchEntry' in remoteSnapshot) &&
|
|
26
|
+
!('prefetchInterface' in remoteSnapshot)
|
|
27
|
+
) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (!remoteSnapshot.prefetchEntry && !remoteSnapshot.prefetchInterface) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
return true;
|
|
35
|
+
};
|
package/src/index.ts
ADDED