@module-federation/vite 1.0.0-alpha-51eeeb6 → 1.0.0-alpha-f87d7d3
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/README.md +3 -3
- package/lib/index.cjs +291 -101
- package/lib/index.esm.js +292 -102
- package/lib/index.modern.js +301 -137
- package/lib/index.umd.js +294 -105
- package/lib/plugins/pluginModuleParseEnd.d.ts +8 -0
- package/lib/utils/PromiseStore.d.ts +16 -0
- package/lib/utils/VirtualModule.d.ts +12 -0
- package/lib/utils/normalizeModuleFederationOptions.d.ts +1 -1
- package/lib/utils/packageNameUtils.d.ts +17 -0
- package/lib/virtualModules/virtualRemoteEntry.d.ts +2 -8
- package/lib/virtualModules/virtualRemotes.d.ts +2 -0
- package/lib/virtualModules/virtualShared_preBuild.d.ts +14 -4
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ https://module-federation.io/guide/basic/webpack.html
|
|
|
23
23
|
// vite.config.js
|
|
24
24
|
import { defineConfig } from 'vite';
|
|
25
25
|
import vue from '@vitejs/plugin-vue';
|
|
26
|
-
import { federation } from 'module-federation
|
|
26
|
+
import { federation } from '@module-federation/vite';
|
|
27
27
|
import topLevelAwait from 'vite-plugin-top-level-await';
|
|
28
28
|
|
|
29
29
|
// https://vitejs.dev/config/
|
|
@@ -43,7 +43,7 @@ export default defineConfig({
|
|
|
43
43
|
// }
|
|
44
44
|
},
|
|
45
45
|
exposes: {
|
|
46
|
-
App: './src/App.vue',
|
|
46
|
+
'./App': './src/App.vue',
|
|
47
47
|
},
|
|
48
48
|
filename: 'dd/remoteEntry.js',
|
|
49
49
|
shared: {
|
|
@@ -59,7 +59,7 @@ export default defineConfig({
|
|
|
59
59
|
server: {
|
|
60
60
|
port: 5173,
|
|
61
61
|
// dev mode please set origin
|
|
62
|
-
origin:
|
|
62
|
+
origin: 'http://localhost:5173',
|
|
63
63
|
},
|
|
64
64
|
build: {
|
|
65
65
|
target: 'chrome89',
|
package/lib/index.cjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
var fs = require('fs');
|
|
2
2
|
var path = require('pathe');
|
|
3
3
|
var pluginutils = require('@rollup/pluginutils');
|
|
4
|
+
var defu = require('defu');
|
|
4
5
|
var estreeWalker = require('estree-walker');
|
|
5
6
|
var MagicString = require('magic-string');
|
|
6
7
|
|
|
@@ -102,6 +103,48 @@ var addEntry = function addEntry(_ref) {
|
|
|
102
103
|
}];
|
|
103
104
|
};
|
|
104
105
|
|
|
106
|
+
var _resolve,
|
|
107
|
+
promise = new Promise(function (resolve, reject) {
|
|
108
|
+
_resolve = resolve;
|
|
109
|
+
});
|
|
110
|
+
var parsePromise = promise;
|
|
111
|
+
var parseStartSet = new Set();
|
|
112
|
+
var parseEndSet = new Set();
|
|
113
|
+
function pluginModuleParseEnd (excludeFn) {
|
|
114
|
+
return [{
|
|
115
|
+
name: "_",
|
|
116
|
+
apply: "serve",
|
|
117
|
+
config: function config() {
|
|
118
|
+
// No waiting in development mode
|
|
119
|
+
_resolve(1);
|
|
120
|
+
}
|
|
121
|
+
}, {
|
|
122
|
+
enforce: "pre",
|
|
123
|
+
name: "parseStart",
|
|
124
|
+
apply: "build",
|
|
125
|
+
load: function load(id) {
|
|
126
|
+
if (excludeFn(id)) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
parseStartSet.add(id);
|
|
130
|
+
}
|
|
131
|
+
}, {
|
|
132
|
+
enforce: "post",
|
|
133
|
+
name: "parseEnd",
|
|
134
|
+
apply: "build",
|
|
135
|
+
moduleParsed: function moduleParsed(module) {
|
|
136
|
+
var id = module.id;
|
|
137
|
+
if (excludeFn(id)) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
parseEndSet.add(id);
|
|
141
|
+
if (parseStartSet.size === parseEndSet.size) {
|
|
142
|
+
_resolve(1);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}];
|
|
146
|
+
}
|
|
147
|
+
|
|
105
148
|
function normalizeExposesItem(key, item) {
|
|
106
149
|
var importPath = '';
|
|
107
150
|
if (typeof item === 'string') {
|
|
@@ -152,7 +195,7 @@ function normalizeRemoteItem(key, remote) {
|
|
|
152
195
|
entryGlobalName: key
|
|
153
196
|
}, remote);
|
|
154
197
|
}
|
|
155
|
-
function removePathFromNpmPackage(packageString) {
|
|
198
|
+
function removePathFromNpmPackage$1(packageString) {
|
|
156
199
|
// 匹配npm包名的正则表达式,忽略路径部分
|
|
157
200
|
var regex = /^(?:@[^/]+\/)?[^/]+/;
|
|
158
201
|
// 使用正则表达式匹配并提取包名
|
|
@@ -163,7 +206,7 @@ function removePathFromNpmPackage(packageString) {
|
|
|
163
206
|
function normalizeShareItem(key, shareItem) {
|
|
164
207
|
var version;
|
|
165
208
|
try {
|
|
166
|
-
version = require(path__namespace.join(removePathFromNpmPackage(key), 'package.json')).version;
|
|
209
|
+
version = require(path__namespace.join(removePathFromNpmPackage$1(key), 'package.json')).version;
|
|
167
210
|
} catch (e) {
|
|
168
211
|
console.log(e);
|
|
169
212
|
}
|
|
@@ -236,62 +279,138 @@ function normalizeModuleFederationOptions(options) {
|
|
|
236
279
|
}
|
|
237
280
|
|
|
238
281
|
/**
|
|
239
|
-
*
|
|
240
|
-
* and
|
|
241
|
-
*
|
|
282
|
+
* Escaping rules:
|
|
283
|
+
* Convert using the format __${mapping}__, where _ and $ are not allowed in npm package names but can be used in variable names.
|
|
284
|
+
* @ => 1
|
|
285
|
+
* / => 2
|
|
286
|
+
* - => 3
|
|
287
|
+
* . => 4
|
|
242
288
|
*/
|
|
243
|
-
var emptyNpmDir = path.resolve(require.resolve("an-empty-js-file"), "../");
|
|
244
289
|
/**
|
|
245
|
-
*
|
|
290
|
+
* @param {*} name "@scope/xx-xx.xx" => "__$1__scope__$2__xx__$3__xx$__4__xx"
|
|
246
291
|
*/
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
var filename = cacheMap2[pkg];
|
|
251
|
-
return filename;
|
|
252
|
-
}
|
|
253
|
-
function getLocalSharedImportMapFileName() {
|
|
254
|
-
var _getNormalizeModuleFe = getNormalizeModuleFederationOptions(),
|
|
255
|
-
name = _getNormalizeModuleFe.name;
|
|
256
|
-
return npmPackageNameToFileName(name) + "_" + "__mf__localSharedImportMap.js";
|
|
292
|
+
function packageNameEncode(name) {
|
|
293
|
+
if (typeof name !== "string") throw new Error("A string package name is required");
|
|
294
|
+
return name.replace(/\@/g, "__$1__").replace(/\//g, "__$2__").replace(/\-/g, "__$3__").replace(/\./g, "__$4__");
|
|
257
295
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
return
|
|
296
|
+
/**
|
|
297
|
+
* @param {*} global "__$1__scope__$2__xx__$3__xx$__4__xx" => "@scope/xx-xx.xx"
|
|
298
|
+
*/
|
|
299
|
+
function packageNameDecode(global) {
|
|
300
|
+
if (typeof global !== "string") throw new Error("A string global variable name is required");
|
|
301
|
+
return global.replace(/\_\_\$1\_\_/g, "@").replace(/\_\_\$2\_\_/g, "/").replace(/\_\_\$3\_\_/g, "-").replace(/\_\_\$4\_\_/g, ".");
|
|
264
302
|
}
|
|
265
|
-
function
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
303
|
+
function removePathFromNpmPackage(packageString) {
|
|
304
|
+
// Regular expression to match npm package name, ignoring path parts
|
|
305
|
+
var regex = /^(?:@[^/]+\/)?[^/]+/;
|
|
306
|
+
// Use regular expression to match and extract the package name
|
|
307
|
+
var match = packageString.match(regex);
|
|
308
|
+
// Return the matched package name or the original string if no match is found
|
|
309
|
+
return match ? match[0] : packageString;
|
|
269
310
|
}
|
|
270
|
-
|
|
311
|
+
|
|
312
|
+
var nodeModulesDir = path.resolve("./node_modules");
|
|
313
|
+
var virtualPackageName = "__mf__virtual";
|
|
314
|
+
try {
|
|
315
|
+
fs.mkdirSync(path.resolve(nodeModulesDir, virtualPackageName));
|
|
316
|
+
} catch (e) {}
|
|
317
|
+
fs.writeFileSync(path.resolve(nodeModulesDir, virtualPackageName, "empty.js"), "");
|
|
318
|
+
fs.writeFileSync(path.resolve(nodeModulesDir, virtualPackageName, "package.json"), JSON.stringify({
|
|
319
|
+
name: virtualPackageName,
|
|
320
|
+
main: "empty.js"
|
|
321
|
+
}));
|
|
271
322
|
/**
|
|
272
|
-
* generate
|
|
323
|
+
* Physically generate files as virtual modules under node_modules/__mf__virtual/*
|
|
273
324
|
*/
|
|
274
|
-
var
|
|
325
|
+
var VirtualModule = /*#__PURE__*/function () {
|
|
326
|
+
function VirtualModule(name) {
|
|
327
|
+
this.originName = void 0;
|
|
328
|
+
this.originName = name;
|
|
329
|
+
}
|
|
330
|
+
var _proto = VirtualModule.prototype;
|
|
331
|
+
_proto.getPath = function getPath() {
|
|
332
|
+
return path.resolve(nodeModulesDir, this.getImportId());
|
|
333
|
+
};
|
|
334
|
+
_proto.getImportId = function getImportId() {
|
|
335
|
+
return virtualPackageName + "/" + packageNameEncode(this.originName);
|
|
336
|
+
};
|
|
337
|
+
_proto.writeSync = function writeSync(code) {
|
|
338
|
+
fs.writeFileSync(this.getPath() + ".js", code);
|
|
339
|
+
};
|
|
340
|
+
_proto.write = function write(code) {
|
|
341
|
+
fs.writeFile(this.getPath() + ".js", code, function () {});
|
|
342
|
+
};
|
|
343
|
+
return VirtualModule;
|
|
344
|
+
}();
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Even the resolveId hook cannot interfere with vite pre-build,
|
|
348
|
+
* and adding query parameter virtual modules will also fail.
|
|
349
|
+
* You can only proxy to the real file through alias
|
|
350
|
+
*/
|
|
351
|
+
// *** __prebuild__
|
|
352
|
+
|
|
353
|
+
var generateLocalSharedImportMap = function generateLocalSharedImportMap() {
|
|
354
|
+
return Promise.resolve(parsePromise).then(function () {
|
|
355
|
+
var options = getNormalizeModuleFederationOptions();
|
|
356
|
+
return "\n const localSharedImportMap = {\n " + Array.from(shareds).map(function (pkg) {
|
|
357
|
+
return "\n " + JSON.stringify(pkg) + ": async () => {\n let pkg = await import(\"" + getPreBuildLibImportId(pkg) + "\")\n return pkg\n }\n ";
|
|
358
|
+
}).join(",") + "\n }\n const localShared = {\n " + Array.from(shareds).map(function (key) {
|
|
359
|
+
var shareItem = options.shared[removePathFromNpmPackage(key)] || options.shared[removePathFromNpmPackage(key) + "/"];
|
|
360
|
+
return "\n " + JSON.stringify(key) + ": {\n name: " + JSON.stringify(key) + ",\n version: " + JSON.stringify(shareItem.version) + ",\n scope: [" + JSON.stringify(shareItem.scope) + "],\n loaded: false,\n from: " + JSON.stringify(options.name) + ",\n async get () {\n localShared[" + JSON.stringify(key) + "].loaded = true\n const {" + JSON.stringify(key) + ": pkgDynamicImport} = localSharedImportMap \n const res = await pkgDynamicImport()\n const exportModule = {...res}\n // All npm packages pre-built by vite will be converted to esm\n Object.defineProperty(exportModule, \"__esModule\", {\n value: true,\n enumerable: false\n })\n return function () {\n return exportModule\n }\n },\n shareConfig: {\n singleton: " + shareItem.shareConfig.singleton + ",\n requiredVersion: " + JSON.stringify(shareItem.shareConfig.requiredVersion) + "\n }\n }\n ";
|
|
361
|
+
}).join(',') + "\n }\n export default localShared\n ";
|
|
362
|
+
});
|
|
363
|
+
};
|
|
364
|
+
// *** __loadShare__
|
|
365
|
+
var writeLocalSharedImportMap = function writeLocalSharedImportMap() {
|
|
366
|
+
try {
|
|
367
|
+
var sharedCount = shareds.size;
|
|
368
|
+
return Promise.resolve(function () {
|
|
369
|
+
if (prevSharedCount !== sharedCount) {
|
|
370
|
+
prevSharedCount = sharedCount;
|
|
371
|
+
var _writeSync = localSharedImportMapModule.writeSync;
|
|
372
|
+
return Promise.resolve(generateLocalSharedImportMap()).then(function (_generateLocalSharedI) {
|
|
373
|
+
return _writeSync.call(localSharedImportMapModule, _generateLocalSharedI);
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
}());
|
|
377
|
+
} catch (e) {
|
|
378
|
+
return Promise.reject(e);
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
var preBuildCacheMap = {};
|
|
382
|
+
var PREBUILD_TAG = "__prebuild__";
|
|
383
|
+
function writePreBuildLibPath(pkg) {
|
|
384
|
+
if (!preBuildCacheMap[pkg]) preBuildCacheMap[pkg] = new VirtualModule(PREBUILD_TAG + pkg);
|
|
385
|
+
preBuildCacheMap[pkg].writeSync("");
|
|
386
|
+
}
|
|
387
|
+
function getPreBuildLibImportId(pkg) {
|
|
388
|
+
if (!preBuildCacheMap[pkg]) preBuildCacheMap[pkg] = new VirtualModule(PREBUILD_TAG + pkg);
|
|
389
|
+
var importId = preBuildCacheMap[pkg].getImportId();
|
|
390
|
+
return importId;
|
|
391
|
+
}
|
|
392
|
+
var shareds = new Set();
|
|
393
|
+
function addShare(pkg) {
|
|
394
|
+
shareds.add(pkg);
|
|
395
|
+
}
|
|
396
|
+
// *** Expose locally provided shared modules here
|
|
397
|
+
var localSharedImportMapModule = new VirtualModule("localSharedImportMap");
|
|
398
|
+
localSharedImportMapModule.writeSync("");
|
|
399
|
+
function getLocalSharedImportMapId() {
|
|
400
|
+
return localSharedImportMapModule.getPath();
|
|
401
|
+
}
|
|
402
|
+
var prevSharedCount = 0;
|
|
403
|
+
var LOAD_SHARE_TAG = "__loadShare__";
|
|
404
|
+
var loadShareCacheMap = {};
|
|
275
405
|
function getLoadShareModulePath(pkg) {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
var filename = cacheMap1[pkg];
|
|
280
|
-
return path.resolve(emptyNpmDir, filename);
|
|
406
|
+
if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = new VirtualModule(LOAD_SHARE_TAG + pkg);
|
|
407
|
+
var filepath = loadShareCacheMap[pkg].getPath();
|
|
408
|
+
return filepath;
|
|
281
409
|
}
|
|
282
410
|
function writeLoadShareModule(pkg, shareItem, command) {
|
|
283
|
-
|
|
284
|
-
}
|
|
285
|
-
function npmPackageNameToFileName(packageName) {
|
|
286
|
-
// 1. 去掉包名前的 "@"
|
|
287
|
-
// 2. 将包名中的 "/" 替换为 "__" 以避免文件路径问题
|
|
288
|
-
// 3. 去掉不合法的文件名字符
|
|
289
|
-
return packageName.replace(/^@/, '') // 移除作用域前缀 "@"
|
|
290
|
-
.replace(/\//g, '__') // 将 "/" 替换为 "__"
|
|
291
|
-
.replace(/[^a-zA-Z0-9_.-]/g, '_'); // 替换其他非法字符为 "_"
|
|
411
|
+
loadShareCacheMap[pkg].writeSync("\n () => import(" + JSON.stringify(getPreBuildLibImportId(pkg)) + ").catch(() => {});\n // dev uses dynamic import to separate chunks\n " + (command !== "build" ? ";() => import(" + JSON.stringify(pkg) + ").catch(() => {});" : '') + "\n const {loadShare} = require(\"@module-federation/runtime\")\n const res = loadShare(" + JSON.stringify(pkg) + ", {\n customShareInfo: {shareConfig:{\n singleton: " + shareItem.shareConfig.singleton + ",\n strictVersion: " + shareItem.shareConfig.strictVersion + ",\n requiredVersion: " + JSON.stringify(shareItem.shareConfig.requiredVersion) + "\n }}})\n const exportModule = " + (command !== "build" ? "/*mf top-level-await placeholder replacement mf*/" : "await ") + "res.then(factory => factory())\n module.exports = exportModule\n ");
|
|
292
412
|
}
|
|
293
413
|
|
|
294
|
-
var emptyPath = require.resolve('an-empty-js-file');
|
|
295
414
|
var REMOTE_ENTRY_ID = 'REMOTE_ENTRY_ID';
|
|
296
415
|
function generateRemoteEntry(options) {
|
|
297
416
|
var pluginImportNames = options.runtimePlugins.map(function (p, i) {
|
|
@@ -301,30 +420,25 @@ function generateRemoteEntry(options) {
|
|
|
301
420
|
return item[1];
|
|
302
421
|
}).join('\n') + "\n\n const exposesMap = {\n " + Object.keys(options.exposes).map(function (key) {
|
|
303
422
|
return "\n " + JSON.stringify(key) + ": async () => {\n const importModule = await import(" + JSON.stringify(options.exposes[key]["import"]) + ")\n const exportModule = {}\n Object.assign(exportModule, importModule)\n Object.defineProperty(exportModule, \"__esModule\", {\n value: true,\n enumerable: false\n })\n return exportModule\n }\n ";
|
|
304
|
-
}).join(',') + "\n }\n import localSharedImportMap from \"" + getLocalSharedImportMapId() + "\"\n async function init(shared = {}) {\n const
|
|
305
|
-
var shareItem = options.shared[key];
|
|
306
|
-
return "\n " + JSON.stringify(key) + ": {\n name: " + JSON.stringify(shareItem.name) + ",\n version: " + JSON.stringify(shareItem.version) + ",\n scope: [" + JSON.stringify(shareItem.scope) + "],\n loaded: false,\n from: " + JSON.stringify(options.name) + ",\n async get () {\n localShared[" + JSON.stringify(key) + "].loaded = true\n const {" + JSON.stringify(key) + ": pkgDynamicImport} = localSharedImportMap \n const res = await pkgDynamicImport()\n const exportModule = {...res}\n // All npm packages pre-built by vite will be converted to esm\n Object.defineProperty(exportModule, \"__esModule\", {\n value: true,\n enumerable: false\n })\n return function () {\n return exportModule\n }\n },\n shareConfig: {\n singleton: " + shareItem.shareConfig.singleton + ",\n requiredVersion: " + JSON.stringify(shareItem.shareConfig.requiredVersion) + "\n }\n }\n ";
|
|
307
|
-
}).join(',') + "\n }\n const initRes = runtimeInit({\n name: " + JSON.stringify(options.name) + ",\n remotes: [" + Object.keys(options.remotes).map(function (key) {
|
|
423
|
+
}).join(',') + "\n }\n import localSharedImportMap from \"" + getLocalSharedImportMapId() + "\"\n async function init(shared = {}) {\n const initRes = runtimeInit({\n name: " + JSON.stringify(options.name) + ",\n remotes: [" + Object.keys(options.remotes).map(function (key) {
|
|
308
424
|
var remote = options.remotes[key];
|
|
309
425
|
return "\n {\n entryGlobalName: " + JSON.stringify(remote.entryGlobalName) + ",\n name: " + JSON.stringify(remote.name) + ",\n type: " + JSON.stringify(remote.type) + ",\n entry: " + JSON.stringify(remote.entry) + ",\n }\n ";
|
|
310
|
-
}).join(',') + "\n ],\n shared:
|
|
426
|
+
}).join(',') + "\n ],\n shared: localSharedImportMap,\n plugins: [" + pluginImportNames.map(function (item) {
|
|
311
427
|
return item[0] + "()";
|
|
312
428
|
}).join(', ') + "]\n });\n initRes.initShareScopeMap('" + options.shareScope + "', shared);\n return initRes\n }\n\n function getExposes(moduleName) {\n if (!(moduleName in exposesMap)) throw new Error(`Module ${moduleName} does not exist in container.`)\n return (exposesMap[moduleName])().then(res => () => res)\n }\n export {\n init,\n getExposes as get\n }\n ";
|
|
313
429
|
}
|
|
314
|
-
var
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
}
|
|
430
|
+
var wrapRemoteEntryModule = new VirtualModule("wrapRemoteEntry");
|
|
431
|
+
wrapRemoteEntryModule.writeSync("\nimport {init, get} from \"" + REMOTE_ENTRY_ID + "\"\nexport {init, get}\n");
|
|
432
|
+
var WRAP_REMOTE_ENTRY_QUERY_STR = wrapRemoteEntryModule.getImportId();
|
|
433
|
+
var WRAP_REMOTE_ENTRY_PATH = wrapRemoteEntryModule.getPath();
|
|
319
434
|
/**
|
|
320
435
|
* Inject entry file, automatically init when used as host,
|
|
321
436
|
* and will not inject remoteEntry
|
|
322
437
|
*/
|
|
323
|
-
var
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
}
|
|
438
|
+
var hostAutoInitModule = new VirtualModule("hostAutoInit");
|
|
439
|
+
hostAutoInitModule.writeSync("\n import {init} from \"" + REMOTE_ENTRY_ID + "\"\n init()\n ");
|
|
440
|
+
var HOST_AUTO_INIT_QUERY_STR = hostAutoInitModule.getImportId();
|
|
441
|
+
var HOST_AUTO_INIT_PATH = hostAutoInitModule.getPath();
|
|
328
442
|
|
|
329
443
|
var filter$1 = pluginutils.createFilter();
|
|
330
444
|
function pluginProxyRemoteEntry () {
|
|
@@ -347,12 +461,6 @@ function pluginProxyRemoteEntry () {
|
|
|
347
461
|
if (id.includes(REMOTE_ENTRY_ID)) {
|
|
348
462
|
return Promise.resolve(generateRemoteEntry(getNormalizeModuleFederationOptions()));
|
|
349
463
|
}
|
|
350
|
-
if (id.includes(WRAP_REMOTE_ENTRY_QUERY_STR)) {
|
|
351
|
-
return Promise.resolve(generateWrapRemoteEntry());
|
|
352
|
-
}
|
|
353
|
-
if (id.includes(HOST_AUTO_INIT_QUERY_STR)) {
|
|
354
|
-
return Promise.resolve(generateWrapHostInit());
|
|
355
|
-
}
|
|
356
464
|
return Promise.resolve();
|
|
357
465
|
} catch (e) {
|
|
358
466
|
return Promise.reject(e);
|
|
@@ -361,6 +469,8 @@ function pluginProxyRemoteEntry () {
|
|
|
361
469
|
};
|
|
362
470
|
}
|
|
363
471
|
|
|
472
|
+
var remoteVirtualModule = new VirtualModule("remoteModule");
|
|
473
|
+
remoteVirtualModule.writeSync("");
|
|
364
474
|
function generateRemotes(id, command) {
|
|
365
475
|
return {
|
|
366
476
|
code: "\n import {loadRemote} from \"@module-federation/runtime\"\n const exportModule = await loadRemote(" + JSON.stringify(id) + ")\n " + (command === "build" && "\n export default 'default' in (exportModule || {}) ? exportModule.default : undefined\n export const __mf__dynamicExports = exportModule\n " || "") + "\n " + (command !== "build" && "\n export default exportModule\n " || "") + "\n ",
|
|
@@ -388,10 +498,11 @@ function pluginProxyRemotes (options) {
|
|
|
388
498
|
find: new RegExp("(" + remote.name + "(/.*|$)?)"),
|
|
389
499
|
replacement: '$1',
|
|
390
500
|
customResolver: function customResolver(source) {
|
|
501
|
+
var requestPath = remoteVirtualModule.getImportId() + '?__moduleRemote__=' + encodeURIComponent(source);
|
|
391
502
|
if (!_config.optimizeDeps) _config.optimizeDeps = {};
|
|
392
503
|
if (!_config.optimizeDeps.needsInterop) _config.optimizeDeps.needsInterop = [];
|
|
393
|
-
if (_config.optimizeDeps.needsInterop.indexOf(
|
|
394
|
-
return this.resolve(
|
|
504
|
+
if (_config.optimizeDeps.needsInterop.indexOf(requestPath) === -1) _config.optimizeDeps.needsInterop.push(requestPath);
|
|
505
|
+
return this.resolve(requestPath);
|
|
395
506
|
}
|
|
396
507
|
});
|
|
397
508
|
});
|
|
@@ -417,6 +528,43 @@ function pluginProxyRemotes (options) {
|
|
|
417
528
|
};
|
|
418
529
|
}
|
|
419
530
|
|
|
531
|
+
/**
|
|
532
|
+
* example:
|
|
533
|
+
* const store = new PromiseStore<number>();
|
|
534
|
+
* store.get("example").then((result) => {
|
|
535
|
+
* console.log("Result from example:", result); // 42
|
|
536
|
+
* });
|
|
537
|
+
* setTimeout(() => {
|
|
538
|
+
* store.set("example", Promise.resolve(42));
|
|
539
|
+
* }, 2000);
|
|
540
|
+
*/
|
|
541
|
+
var PromiseStore = /*#__PURE__*/function () {
|
|
542
|
+
function PromiseStore() {
|
|
543
|
+
this.promiseMap = new Map();
|
|
544
|
+
this.resolveMap = new Map();
|
|
545
|
+
}
|
|
546
|
+
var _proto = PromiseStore.prototype;
|
|
547
|
+
_proto.set = function set(id, promise) {
|
|
548
|
+
if (this.resolveMap.has(id)) {
|
|
549
|
+
promise.then(this.resolveMap.get(id));
|
|
550
|
+
this.resolveMap["delete"](id);
|
|
551
|
+
}
|
|
552
|
+
this.promiseMap.set(id, promise);
|
|
553
|
+
};
|
|
554
|
+
_proto.get = function get(id) {
|
|
555
|
+
var _this = this;
|
|
556
|
+
if (this.promiseMap.has(id)) {
|
|
557
|
+
return this.promiseMap.get(id);
|
|
558
|
+
}
|
|
559
|
+
var pendingPromise = new Promise(function (resolve) {
|
|
560
|
+
_this.resolveMap.set(id, resolve);
|
|
561
|
+
});
|
|
562
|
+
this.promiseMap.set(id, pendingPromise);
|
|
563
|
+
return pendingPromise;
|
|
564
|
+
};
|
|
565
|
+
return PromiseStore;
|
|
566
|
+
}();
|
|
567
|
+
|
|
420
568
|
function wrapManualChunks(output, manualChunksCb) {
|
|
421
569
|
if (!output.manualChunks) output.manualChunks = {};
|
|
422
570
|
var wrapManualChunks = function wrapManualChunks(original) {
|
|
@@ -441,9 +589,24 @@ function proxySharedModule(options) {
|
|
|
441
589
|
include = options.include,
|
|
442
590
|
exclude = options.exclude;
|
|
443
591
|
var filterFunction = pluginutils.createFilter(include, exclude);
|
|
444
|
-
writeLocalSharedImportMap(Object.keys(shared));
|
|
445
592
|
return [{
|
|
446
|
-
name:
|
|
593
|
+
name: "generateLocalSharedImportMap",
|
|
594
|
+
enforce: "post",
|
|
595
|
+
resolveId: function resolveId(id) {
|
|
596
|
+
if (id.includes(getLocalSharedImportMapId())) return id;
|
|
597
|
+
},
|
|
598
|
+
load: function load(id) {
|
|
599
|
+
if (id.includes(getLocalSharedImportMapId())) {
|
|
600
|
+
return generateLocalSharedImportMap();
|
|
601
|
+
}
|
|
602
|
+
},
|
|
603
|
+
transform: function transform(code, id) {
|
|
604
|
+
if (id.includes(getLocalSharedImportMapId())) {
|
|
605
|
+
return generateLocalSharedImportMap();
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
}, {
|
|
609
|
+
name: 'proxyPreBuildShared',
|
|
447
610
|
enforce: 'post',
|
|
448
611
|
config: function config(_config, _ref) {
|
|
449
612
|
var _config$resolve$alias, _config$resolve$alias2;
|
|
@@ -452,50 +615,77 @@ function proxySharedModule(options) {
|
|
|
452
615
|
if (!_config.build.rollupOptions) _config.build.rollupOptions = {};
|
|
453
616
|
var rollupOptions = _config.build.rollupOptions;
|
|
454
617
|
if (!rollupOptions.output) rollupOptions.output = {};
|
|
455
|
-
// config?.optimizeDeps?.include?.push?.("an-empty-js-file");
|
|
456
|
-
// config.optimizeDeps.needsInterop.push('an-empty-js-file');
|
|
457
618
|
wrapManualChunks(_config.build.rollupOptions.output, function (id) {
|
|
619
|
+
// https://github.com/module-federation/vite/issues/40#issuecomment-2311434503
|
|
620
|
+
if (id.includes('/preload-helper.js')) {
|
|
621
|
+
return "preload-helper";
|
|
622
|
+
}
|
|
458
623
|
if (id.includes("node_modules/@module-federation/runtime")) {
|
|
459
624
|
return "@module-federation/runtime";
|
|
460
625
|
}
|
|
461
|
-
if (id.includes(LOAD_SHARE_TAG) || id.includes("__mf__prebuildwrap_")) {
|
|
462
|
-
return id.split("/").pop();
|
|
463
|
-
}
|
|
464
626
|
});
|
|
465
627
|
(_config$resolve$alias = _config.resolve.alias).push.apply(_config$resolve$alias, Object.keys(shared).map(function (key) {
|
|
466
|
-
var
|
|
467
|
-
_config == null || (_config$optimizeDeps = _config.optimizeDeps) == null || (_config$optimizeDeps = _config$optimizeDeps.include) == null || _config$optimizeDeps.push == null || _config$optimizeDeps.push(getPreBuildLibPath(key));
|
|
468
|
-
// write proxyFile
|
|
469
|
-
writeLoadShareModule(key, shared[key], command);
|
|
470
|
-
var preBuildLibPath = getLoadShareModulePath(key);
|
|
471
|
-
_config == null || (_config$optimizeDeps2 = _config.optimizeDeps) == null || (_config$optimizeDeps2 = _config$optimizeDeps2.needsInterop) == null || _config$optimizeDeps2.push(key);
|
|
628
|
+
var pattern = key.endsWith("/") ? "(^" + key.replace(/\/$/, "") + "(/.+)?$)" : "(^" + key + "$)";
|
|
472
629
|
return {
|
|
473
|
-
// Intercept all
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
replacement: preBuildLibPath,
|
|
630
|
+
// Intercept all shared requests and proxy them to loadShare
|
|
631
|
+
find: new RegExp(pattern),
|
|
632
|
+
replacement: "$1",
|
|
477
633
|
customResolver: function customResolver(source, importer) {
|
|
478
|
-
var _config$
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
634
|
+
var _config$optimizeDeps;
|
|
635
|
+
var loadSharePath = getLoadShareModulePath(source);
|
|
636
|
+
_config == null || (_config$optimizeDeps = _config.optimizeDeps) == null || (_config$optimizeDeps = _config$optimizeDeps.needsInterop) == null || _config$optimizeDeps.push(loadSharePath);
|
|
637
|
+
writeLoadShareModule(source, shared[key], command);
|
|
638
|
+
writePreBuildLibPath(source);
|
|
639
|
+
addShare(source);
|
|
640
|
+
writeLocalSharedImportMap();
|
|
641
|
+
return this.resolve(loadSharePath);
|
|
484
642
|
}
|
|
485
643
|
};
|
|
486
644
|
}));
|
|
645
|
+
var savePrebuild = new PromiseStore();
|
|
487
646
|
(_config$resolve$alias2 = _config.resolve.alias).push.apply(_config$resolve$alias2, Object.keys(shared).map(function (key) {
|
|
488
647
|
return command === "build" ? {
|
|
489
|
-
find: new RegExp("
|
|
490
|
-
replacement:
|
|
648
|
+
find: new RegExp(virtualPackageName + "/" + PREBUILD_TAG + "(.+)"),
|
|
649
|
+
replacement: function replacement(_, $1) {
|
|
650
|
+
return packageNameDecode($1);
|
|
651
|
+
}
|
|
491
652
|
} : {
|
|
492
|
-
find: new RegExp("
|
|
653
|
+
find: new RegExp(virtualPackageName + "/" + PREBUILD_TAG + "(.+)"),
|
|
654
|
+
replacement: "$1",
|
|
493
655
|
customResolver: function customResolver(source, importer) {
|
|
494
|
-
|
|
656
|
+
try {
|
|
657
|
+
var _this = this;
|
|
658
|
+
if (importer.includes(LOAD_SHARE_TAG)) {
|
|
659
|
+
// save pre-bunding module id
|
|
660
|
+
savePrebuild.set(source, _this.resolve(packageNameDecode(source)).then(function (item) {
|
|
661
|
+
return item.id;
|
|
662
|
+
}));
|
|
663
|
+
}
|
|
664
|
+
// Fix localSharedImportMap import id
|
|
665
|
+
var _resolve = _this.resolve;
|
|
666
|
+
return Promise.resolve(savePrebuild.get(source)).then(function (_savePrebuild$get) {
|
|
667
|
+
return Promise.resolve(_resolve.call(_this, _savePrebuild$get));
|
|
668
|
+
});
|
|
669
|
+
} catch (e) {
|
|
670
|
+
return Promise.reject(e);
|
|
671
|
+
}
|
|
495
672
|
}
|
|
496
673
|
};
|
|
497
674
|
}));
|
|
498
675
|
}
|
|
676
|
+
}, {
|
|
677
|
+
name: "watchLocalSharedImportMap",
|
|
678
|
+
apply: "serve",
|
|
679
|
+
config: function config(_config2) {
|
|
680
|
+
_config2.server = defu.defu(_config2.server, {
|
|
681
|
+
watch: {
|
|
682
|
+
ignored: []
|
|
683
|
+
}
|
|
684
|
+
});
|
|
685
|
+
var watch = _config2.server.watch;
|
|
686
|
+
watch.ignored = [].concat(watch.ignored);
|
|
687
|
+
watch.ignored.push("!**/node_modules/" + localSharedImportMapModule.getImportId() + ".js");
|
|
688
|
+
}
|
|
499
689
|
}, {
|
|
500
690
|
name: "prebuild-top-level-await",
|
|
501
691
|
apply: "serve",
|
|
@@ -515,7 +705,6 @@ function proxySharedModule(options) {
|
|
|
515
705
|
var magicString = new MagicString__default["default"](code);
|
|
516
706
|
estreeWalker.walk(ast, {
|
|
517
707
|
enter: function enter(node) {
|
|
518
|
-
// 处理命名导出
|
|
519
708
|
if (node.type === 'ExportNamedDeclaration' && node.specifiers) {
|
|
520
709
|
var exportSpecifiers = node.specifiers.map(function (specifier) {
|
|
521
710
|
return specifier.exported.name;
|
|
@@ -531,7 +720,6 @@ function proxySharedModule(options) {
|
|
|
531
720
|
var replacement = proxyStatements + "\nexport { " + exportStatements + " };";
|
|
532
721
|
magicString.overwrite(start, end, replacement);
|
|
533
722
|
}
|
|
534
|
-
// 处理默认导出
|
|
535
723
|
if (node.type === 'ExportDefaultDeclaration') {
|
|
536
724
|
var declaration = node.declaration;
|
|
537
725
|
var _start = node.start;
|
|
@@ -539,14 +727,14 @@ function proxySharedModule(options) {
|
|
|
539
727
|
var proxyStatement;
|
|
540
728
|
var exportStatement = 'default';
|
|
541
729
|
if (declaration.type === 'Identifier') {
|
|
542
|
-
//
|
|
730
|
+
// example: export default foo;
|
|
543
731
|
proxyStatement = "\n const __mfproxy__awaitdefault = await " + declaration.name + "();\n const __mfproxy__default = __mfproxy__awaitdefault;\n ";
|
|
544
732
|
} else if (declaration.type === 'CallExpression' || declaration.type === 'FunctionDeclaration') {
|
|
545
|
-
//
|
|
733
|
+
// example: export default someFunction();
|
|
546
734
|
var declarationCode = code.slice(declaration.start, declaration.end);
|
|
547
735
|
proxyStatement = "\n const __mfproxy__awaitdefault = await (" + declarationCode + ");\n const __mfproxy__default = __mfproxy__awaitdefault;\n ";
|
|
548
736
|
} else {
|
|
549
|
-
//
|
|
737
|
+
// other
|
|
550
738
|
proxyStatement = "\n const __mfproxy__awaitdefault = await (" + code.slice(declaration.start, declaration.end) + ");\n const __mfproxy__default = __mfproxy__awaitdefault;\n ";
|
|
551
739
|
}
|
|
552
740
|
var _replacement = proxyStatement + "\nexport { __mfproxy__default as " + exportStatement + " };";
|
|
@@ -609,7 +797,9 @@ function federation(mfUserOptions) {
|
|
|
609
797
|
}), addEntry({
|
|
610
798
|
entryName: 'hostInit',
|
|
611
799
|
entryPath: HOST_AUTO_INIT_PATH
|
|
612
|
-
}), [pluginProxyRemoteEntry(), pluginProxyRemotes(options)],
|
|
800
|
+
}), [pluginProxyRemoteEntry(), pluginProxyRemotes(options)], pluginModuleParseEnd(function (id) {
|
|
801
|
+
return id.includes(HOST_AUTO_INIT_QUERY_STR) || id.includes(WRAP_REMOTE_ENTRY_QUERY_STR) || id.includes(REMOTE_ENTRY_ID) || id.includes(getLocalSharedImportMapId());
|
|
802
|
+
}), proxySharedModule({
|
|
613
803
|
shared: shared
|
|
614
804
|
}), [{
|
|
615
805
|
name: 'module-federation-vite',
|