@module-federation/vite 1.0.0 → 1.1.0
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 +88 -54
- package/lib/index.cjs +134 -150
- package/lib/index.esm.js +134 -150
- package/lib/index.modern.js +148 -164
- package/lib/index.umd.js +134 -150
- package/lib/plugins/pluginDevProxyModuleTopLevelAwait.d.ts +1 -1
- package/lib/plugins/pluginModuleParseEnd.d.ts +1 -1
- package/lib/plugins/pluginProxyRemotes.d.ts +2 -2
- package/lib/utils/__tests__/normalizeModuleFederationOption.test.d.ts +1 -0
- package/lib/utils/logUtils.d.ts +1 -0
- package/lib/utils/normalizeModuleFederationOptions.d.ts +39 -7
- package/lib/virtualModules/index.d.ts +5 -4
- package/lib/virtualModules/virtualExposes.d.ts +2 -0
- package/lib/virtualModules/virtualRuntimeInitStatus.d.ts +1 -1
- package/lib/virtualModules/virtualShared_preBuild.d.ts +5 -5
- package/package.json +11 -4
package/lib/index.modern.js
CHANGED
|
@@ -12,13 +12,13 @@ const addEntry = ({
|
|
|
12
12
|
entryPath,
|
|
13
13
|
fileName
|
|
14
14
|
}) => {
|
|
15
|
-
const devEntryPath = entryPath.startsWith(
|
|
15
|
+
const devEntryPath = entryPath.startsWith('virtual:mf') ? '/@id/' + entryPath : entryPath;
|
|
16
16
|
let entryFiles = [];
|
|
17
17
|
let htmlFilePath;
|
|
18
18
|
let _command;
|
|
19
19
|
return [{
|
|
20
20
|
name: 'add-entry',
|
|
21
|
-
apply:
|
|
21
|
+
apply: 'serve',
|
|
22
22
|
config(config, {
|
|
23
23
|
command
|
|
24
24
|
}) {
|
|
@@ -47,8 +47,8 @@ const addEntry = ({
|
|
|
47
47
|
return c.replace('<head>', `<head><script type="module" src=${JSON.stringify(devEntryPath.replace(/.+?\:([/\\])[/\\]?/, '$1').replace(/\\\\?/g, '/'))}></script>`);
|
|
48
48
|
}
|
|
49
49
|
}, {
|
|
50
|
-
name:
|
|
51
|
-
enforce:
|
|
50
|
+
name: 'add-entry',
|
|
51
|
+
enforce: 'post',
|
|
52
52
|
configResolved(config) {
|
|
53
53
|
const inputOptions = config.build.rollupOptions.input;
|
|
54
54
|
if (!inputOptions) {
|
|
@@ -65,8 +65,8 @@ const addEntry = ({
|
|
|
65
65
|
}
|
|
66
66
|
},
|
|
67
67
|
buildStart() {
|
|
68
|
-
if (_command ===
|
|
69
|
-
const hasHash = fileName == null || fileName.includes == null ? void 0 : fileName.includes(
|
|
68
|
+
if (_command === 'serve') return;
|
|
69
|
+
const hasHash = fileName == null || fileName.includes == null ? void 0 : fileName.includes('[hash');
|
|
70
70
|
const emitFileOptions = {
|
|
71
71
|
name: entryName,
|
|
72
72
|
type: 'chunk',
|
|
@@ -103,10 +103,10 @@ const addEntry = ({
|
|
|
103
103
|
function PluginDevProxyModuleTopLevelAwait() {
|
|
104
104
|
const filterFunction = createFilter();
|
|
105
105
|
return {
|
|
106
|
-
name:
|
|
107
|
-
apply:
|
|
106
|
+
name: 'dev-proxy-module-top-level-await',
|
|
107
|
+
apply: 'serve',
|
|
108
108
|
transform(code, id) {
|
|
109
|
-
if (!code.includes(
|
|
109
|
+
if (!code.includes('/*mf top-level-await placeholder replacement mf*/')) {
|
|
110
110
|
return null;
|
|
111
111
|
}
|
|
112
112
|
if (!filterFunction(id)) return null;
|
|
@@ -174,6 +174,18 @@ function PluginDevProxyModuleTopLevelAwait() {
|
|
|
174
174
|
};
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
+
function _extends() {
|
|
178
|
+
return _extends = Object.assign ? Object.assign.bind() : function (n) {
|
|
179
|
+
for (var e = 1; e < arguments.length; e++) {
|
|
180
|
+
var t = arguments[e];
|
|
181
|
+
for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
|
|
182
|
+
}
|
|
183
|
+
return n;
|
|
184
|
+
}, _extends.apply(null, arguments);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const warn = message => message.split('\n').forEach(msg => console.warn('\x1b[33m%s\x1b[0m', msg));
|
|
188
|
+
|
|
177
189
|
function normalizeExposesItem(key, item) {
|
|
178
190
|
let importPath = '';
|
|
179
191
|
if (typeof item === 'string') {
|
|
@@ -246,7 +258,7 @@ function normalizeShareItem(key, shareItem) {
|
|
|
246
258
|
from: '',
|
|
247
259
|
shareConfig: {
|
|
248
260
|
singleton: false,
|
|
249
|
-
requiredVersion: `^${version}`
|
|
261
|
+
requiredVersion: version ? `^${version}` : '*'
|
|
250
262
|
}
|
|
251
263
|
};
|
|
252
264
|
}
|
|
@@ -257,7 +269,7 @@ function normalizeShareItem(key, shareItem) {
|
|
|
257
269
|
scope: shareItem.shareScope || 'default',
|
|
258
270
|
shareConfig: {
|
|
259
271
|
singleton: shareItem.singleton || false,
|
|
260
|
-
requiredVersion: shareItem.requiredVersion || `^${version}`
|
|
272
|
+
requiredVersion: shareItem.requiredVersion || (version ? `^${version}` : '*'),
|
|
261
273
|
strictVersion: !!shareItem.strictVersion
|
|
262
274
|
}
|
|
263
275
|
};
|
|
@@ -283,13 +295,13 @@ function normalizeLibrary(library) {
|
|
|
283
295
|
return library;
|
|
284
296
|
}
|
|
285
297
|
function normalizeManifest(manifest = false) {
|
|
286
|
-
if (typeof manifest ===
|
|
298
|
+
if (typeof manifest === 'boolean') {
|
|
287
299
|
return manifest;
|
|
288
300
|
}
|
|
289
301
|
return Object.assign({
|
|
290
|
-
filePath:
|
|
302
|
+
filePath: '',
|
|
291
303
|
disableAssetsAnalyze: false,
|
|
292
|
-
fileName:
|
|
304
|
+
fileName: 'mf-manifest.json'
|
|
293
305
|
}, manifest);
|
|
294
306
|
}
|
|
295
307
|
let config;
|
|
@@ -298,10 +310,13 @@ function getNormalizeModuleFederationOptions() {
|
|
|
298
310
|
}
|
|
299
311
|
function getNormalizeShareItem(key) {
|
|
300
312
|
const options = getNormalizeModuleFederationOptions();
|
|
301
|
-
const shareItem = options.shared[removePathFromNpmPackage(key)] || options.shared[removePathFromNpmPackage(key) +
|
|
313
|
+
const shareItem = options.shared[removePathFromNpmPackage(key)] || options.shared[removePathFromNpmPackage(key) + '/'];
|
|
302
314
|
return shareItem;
|
|
303
315
|
}
|
|
304
316
|
function normalizeModuleFederationOptions(options) {
|
|
317
|
+
if (options.getPublicPath || options.publicPath) {
|
|
318
|
+
warn(`We are ignoring the getPublicPath and publicPath options because they are natively supported by Vite\nwith the "experimental.renderBuiltUrl" configuration https://vitejs.dev/guide/build#advanced-base-options`);
|
|
319
|
+
}
|
|
305
320
|
return config = {
|
|
306
321
|
exposes: normalizeExposes(options.exposes),
|
|
307
322
|
filename: options.filename || 'remoteEntry-[hash]',
|
|
@@ -313,11 +328,11 @@ function normalizeModuleFederationOptions(options) {
|
|
|
313
328
|
shareScope: options.shareScope || 'default',
|
|
314
329
|
shared: normalizeShared(options.shared),
|
|
315
330
|
runtimePlugins: options.runtimePlugins || [],
|
|
316
|
-
getPublicPath: options.getPublicPath,
|
|
317
331
|
implementation: options.implementation,
|
|
318
332
|
manifest: normalizeManifest(options.manifest),
|
|
319
333
|
dev: options.dev,
|
|
320
|
-
dts: options.dts
|
|
334
|
+
dts: options.dts,
|
|
335
|
+
shareStrategy: options.shareStrategy
|
|
321
336
|
};
|
|
322
337
|
}
|
|
323
338
|
|
|
@@ -335,8 +350,8 @@ function normalizeModuleFederationOptions(options) {
|
|
|
335
350
|
* @returns {string} - The encoded file name.
|
|
336
351
|
*/
|
|
337
352
|
function packageNameEncode(name) {
|
|
338
|
-
if (typeof name !==
|
|
339
|
-
return name.replace(/@/g,
|
|
353
|
+
if (typeof name !== 'string') throw new Error('A string package name is required');
|
|
354
|
+
return name.replace(/@/g, '_mf_0_').replace(/\//g, '_mf_1_').replace(/-/g, '_mf_2_').replace(/\./g, '_mf_3_');
|
|
340
355
|
}
|
|
341
356
|
/**
|
|
342
357
|
* Decodes an encoded file name back to the original package name.
|
|
@@ -344,8 +359,8 @@ function packageNameEncode(name) {
|
|
|
344
359
|
* @returns {string} - The decoded package name.
|
|
345
360
|
*/
|
|
346
361
|
function packageNameDecode(encoded) {
|
|
347
|
-
if (typeof encoded !==
|
|
348
|
-
return encoded.replace(/_mf_0_/g,
|
|
362
|
+
if (typeof encoded !== 'string') throw new Error('A string encoded file name is required');
|
|
363
|
+
return encoded.replace(/_mf_0_/g, '@').replace(/_mf_1_/g, '/').replace(/_mf_2_/g, '-').replace(/_mf_3_/g, '.');
|
|
349
364
|
}
|
|
350
365
|
|
|
351
366
|
/**
|
|
@@ -355,11 +370,11 @@ function getLocalSharedImportMapPath_temp() {
|
|
|
355
370
|
const {
|
|
356
371
|
name
|
|
357
372
|
} = getNormalizeModuleFederationOptions();
|
|
358
|
-
return path__default.resolve(
|
|
373
|
+
return path__default.resolve('.__mf__temp', packageNameEncode(name), 'localSharedImportMap');
|
|
359
374
|
}
|
|
360
375
|
function writeLocalSharedImportMap_temp(content) {
|
|
361
376
|
const localSharedImportMapId = getLocalSharedImportMapPath_temp();
|
|
362
|
-
createFile(localSharedImportMapId +
|
|
377
|
+
createFile(localSharedImportMapId + '.js', '\n// Windows temporarily needs this file, https://github.com/module-federation/vite/issues/68\n' + content);
|
|
363
378
|
}
|
|
364
379
|
function createFile(filePath, content) {
|
|
365
380
|
const dir = path__default.dirname(filePath);
|
|
@@ -378,16 +393,16 @@ const nodeModulesDir = function findNodeModulesDir(startDir = process.cwd()) {
|
|
|
378
393
|
}
|
|
379
394
|
currentDir = dirname(currentDir);
|
|
380
395
|
}
|
|
381
|
-
return
|
|
396
|
+
return '';
|
|
382
397
|
}();
|
|
383
|
-
const virtualPackageName =
|
|
398
|
+
const virtualPackageName = '__mf__virtual';
|
|
384
399
|
if (!existsSync(resolve(nodeModulesDir, virtualPackageName))) {
|
|
385
400
|
mkdirSync(resolve(nodeModulesDir, virtualPackageName));
|
|
386
401
|
}
|
|
387
|
-
writeFileSync(resolve(nodeModulesDir, virtualPackageName,
|
|
388
|
-
writeFileSync(resolve(nodeModulesDir, virtualPackageName,
|
|
402
|
+
writeFileSync(resolve(nodeModulesDir, virtualPackageName, 'empty.js'), '');
|
|
403
|
+
writeFileSync(resolve(nodeModulesDir, virtualPackageName, 'package.json'), JSON.stringify({
|
|
389
404
|
name: virtualPackageName,
|
|
390
|
-
main:
|
|
405
|
+
main: 'empty.js'
|
|
391
406
|
}));
|
|
392
407
|
const patternMap = {};
|
|
393
408
|
const cacheMap = {};
|
|
@@ -395,13 +410,13 @@ const cacheMap = {};
|
|
|
395
410
|
* Physically generate files as virtual modules under node_modules/__mf__virtual/*
|
|
396
411
|
*/
|
|
397
412
|
class VirtualModule {
|
|
398
|
-
static findModule(tag, str =
|
|
413
|
+
static findModule(tag, str = '') {
|
|
399
414
|
if (!patternMap[tag]) patternMap[tag] = new RegExp(`(.*${packageNameEncode(tag)}(.+?)${packageNameEncode(tag)}.*)`);
|
|
400
415
|
const moduleName = (str.match(patternMap[tag]) || [])[2];
|
|
401
416
|
if (moduleName) return cacheMap[tag][packageNameDecode(moduleName)];
|
|
402
417
|
return undefined;
|
|
403
418
|
}
|
|
404
|
-
constructor(name, tag = '__mf_v__', suffix =
|
|
419
|
+
constructor(name, tag = '__mf_v__', suffix = '') {
|
|
405
420
|
var _name$split$slice$pop;
|
|
406
421
|
this.name = void 0;
|
|
407
422
|
this.tag = void 0;
|
|
@@ -409,7 +424,7 @@ class VirtualModule {
|
|
|
409
424
|
this.inited = false;
|
|
410
425
|
this.name = name;
|
|
411
426
|
this.tag = tag;
|
|
412
|
-
this.suffix = suffix || ((_name$split$slice$pop = name.split(
|
|
427
|
+
this.suffix = suffix || ((_name$split$slice$pop = name.split('.').slice(1).pop()) == null ? void 0 : _name$split$slice$pop.replace(/(.)/, '.$1')) || '.js';
|
|
413
428
|
if (!cacheMap[this.tag]) cacheMap[this.tag] = {};
|
|
414
429
|
cacheMap[this.tag][this.name] = this;
|
|
415
430
|
}
|
|
@@ -434,7 +449,30 @@ class VirtualModule {
|
|
|
434
449
|
}
|
|
435
450
|
}
|
|
436
451
|
|
|
437
|
-
const
|
|
452
|
+
const VIRTUAL_EXPOSES = 'virtual:mf-exposes';
|
|
453
|
+
function generateExposes() {
|
|
454
|
+
const options = getNormalizeModuleFederationOptions();
|
|
455
|
+
return `
|
|
456
|
+
export default {
|
|
457
|
+
${Object.keys(options.exposes).map(key => {
|
|
458
|
+
return `
|
|
459
|
+
${JSON.stringify(key)}: async () => {
|
|
460
|
+
const importModule = await import(${JSON.stringify(options.exposes[key].import)})
|
|
461
|
+
const exportModule = {}
|
|
462
|
+
Object.assign(exportModule, importModule)
|
|
463
|
+
Object.defineProperty(exportModule, "__esModule", {
|
|
464
|
+
value: true,
|
|
465
|
+
enumerable: false
|
|
466
|
+
})
|
|
467
|
+
return exportModule
|
|
468
|
+
}
|
|
469
|
+
`;
|
|
470
|
+
}).join(',')}
|
|
471
|
+
}
|
|
472
|
+
`;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
const virtualRuntimeInitStatus = new VirtualModule('runtimeInit');
|
|
438
476
|
function writeRuntimeInitStatus() {
|
|
439
477
|
virtualRuntimeInitStatus.writeSync(`
|
|
440
478
|
let initResolve, initReject
|
|
@@ -454,7 +492,7 @@ const cacheRemoteMap = {};
|
|
|
454
492
|
const LOAD_REMOTE_TAG = '__loadRemote__';
|
|
455
493
|
function getRemoteVirtualModule(remote, command) {
|
|
456
494
|
if (!cacheRemoteMap[remote]) {
|
|
457
|
-
cacheRemoteMap[remote] = new VirtualModule(remote, LOAD_REMOTE_TAG,
|
|
495
|
+
cacheRemoteMap[remote] = new VirtualModule(remote, LOAD_REMOTE_TAG, '.js');
|
|
458
496
|
cacheRemoteMap[remote].writeSync(generateRemotes(remote, command));
|
|
459
497
|
}
|
|
460
498
|
const virtual = cacheRemoteMap[remote];
|
|
@@ -475,7 +513,7 @@ function generateRemotes(id, command) {
|
|
|
475
513
|
const {loadRemote} = require("@module-federation/runtime")
|
|
476
514
|
const {initPromise} = require("${virtualRuntimeInitStatus.getImportId()}")
|
|
477
515
|
const res = initPromise.then(_ => loadRemote(${JSON.stringify(id)}))
|
|
478
|
-
const exportModule = ${command !==
|
|
516
|
+
const exportModule = ${command !== 'build' ? '/*mf top-level-await placeholder replacement mf*/' : 'await '}initPromise.then(_ => res)
|
|
479
517
|
module.exports = exportModule
|
|
480
518
|
`;
|
|
481
519
|
}
|
|
@@ -487,10 +525,10 @@ function generateRemotes(id, command) {
|
|
|
487
525
|
*/
|
|
488
526
|
// *** __prebuild__
|
|
489
527
|
const preBuildCacheMap = {};
|
|
490
|
-
const PREBUILD_TAG =
|
|
528
|
+
const PREBUILD_TAG = '__prebuild__';
|
|
491
529
|
function writePreBuildLibPath(pkg) {
|
|
492
530
|
if (!preBuildCacheMap[pkg]) preBuildCacheMap[pkg] = new VirtualModule(pkg, PREBUILD_TAG);
|
|
493
|
-
preBuildCacheMap[pkg].writeSync(
|
|
531
|
+
preBuildCacheMap[pkg].writeSync('');
|
|
494
532
|
}
|
|
495
533
|
function getPreBuildLibImportId(pkg) {
|
|
496
534
|
if (!preBuildCacheMap[pkg]) preBuildCacheMap[pkg] = new VirtualModule(pkg, PREBUILD_TAG);
|
|
@@ -498,10 +536,10 @@ function getPreBuildLibImportId(pkg) {
|
|
|
498
536
|
return importId;
|
|
499
537
|
}
|
|
500
538
|
// *** __loadShare__
|
|
501
|
-
const LOAD_SHARE_TAG =
|
|
539
|
+
const LOAD_SHARE_TAG = '__loadShare__';
|
|
502
540
|
const loadShareCacheMap = {};
|
|
503
541
|
function getLoadShareModulePath(pkg) {
|
|
504
|
-
if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = new VirtualModule(pkg, LOAD_SHARE_TAG,
|
|
542
|
+
if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = new VirtualModule(pkg, LOAD_SHARE_TAG, '.js');
|
|
505
543
|
const filepath = loadShareCacheMap[pkg].getPath();
|
|
506
544
|
return filepath;
|
|
507
545
|
}
|
|
@@ -510,7 +548,7 @@ function writeLoadShareModule(pkg, shareItem, command) {
|
|
|
510
548
|
|
|
511
549
|
;() => import(${JSON.stringify(getPreBuildLibImportId(pkg))}).catch(() => {});
|
|
512
550
|
// dev uses dynamic import to separate chunks
|
|
513
|
-
${command !==
|
|
551
|
+
${command !== 'build' ? `;() => import(${JSON.stringify(pkg)}).catch(() => {});` : ''}
|
|
514
552
|
const {loadShare} = require("@module-federation/runtime")
|
|
515
553
|
const {initPromise} = require("${virtualRuntimeInitStatus.getImportId()}")
|
|
516
554
|
const res = initPromise.then(_ => loadShare(${JSON.stringify(pkg)}, {
|
|
@@ -519,7 +557,7 @@ function writeLoadShareModule(pkg, shareItem, command) {
|
|
|
519
557
|
strictVersion: ${shareItem.shareConfig.strictVersion},
|
|
520
558
|
requiredVersion: ${JSON.stringify(shareItem.shareConfig.requiredVersion)}
|
|
521
559
|
}}}))
|
|
522
|
-
const exportModule = ${command !==
|
|
560
|
+
const exportModule = ${command !== 'build' ? '/*mf top-level-await placeholder replacement mf*/' : 'await '}res.then(factory => factory())
|
|
523
561
|
module.exports = exportModule
|
|
524
562
|
`);
|
|
525
563
|
}
|
|
@@ -532,7 +570,7 @@ function addUsedShares(pkg) {
|
|
|
532
570
|
usedShares.add(pkg);
|
|
533
571
|
}
|
|
534
572
|
// *** Expose locally provided shared modules here
|
|
535
|
-
new VirtualModule(
|
|
573
|
+
new VirtualModule('localSharedImportMap');
|
|
536
574
|
function getLocalSharedImportMapPath() {
|
|
537
575
|
return getLocalSharedImportMapPath_temp();
|
|
538
576
|
// return localSharedImportMapModule.getPath()
|
|
@@ -555,7 +593,7 @@ function generateLocalSharedImportMap() {
|
|
|
555
593
|
let pkg = await import("${getPreBuildLibImportId(pkg)}")
|
|
556
594
|
return pkg
|
|
557
595
|
}
|
|
558
|
-
`).join(
|
|
596
|
+
`).join(',')}
|
|
559
597
|
}
|
|
560
598
|
const usedShared = {
|
|
561
599
|
${Array.from(getUsedShares()).map(key => {
|
|
@@ -613,23 +651,7 @@ function generateRemoteEntry(options) {
|
|
|
613
651
|
return `
|
|
614
652
|
import {init as runtimeInit, loadRemote} from "@module-federation/runtime";
|
|
615
653
|
${pluginImportNames.map(item => item[1]).join('\n')}
|
|
616
|
-
|
|
617
|
-
const exposesMap = {
|
|
618
|
-
${Object.keys(options.exposes).map(key => {
|
|
619
|
-
return `
|
|
620
|
-
${JSON.stringify(key)}: async () => {
|
|
621
|
-
const importModule = await import(${JSON.stringify(options.exposes[key].import)})
|
|
622
|
-
const exportModule = {}
|
|
623
|
-
Object.assign(exportModule, importModule)
|
|
624
|
-
Object.defineProperty(exportModule, "__esModule", {
|
|
625
|
-
value: true,
|
|
626
|
-
enumerable: false
|
|
627
|
-
})
|
|
628
|
-
return exportModule
|
|
629
|
-
}
|
|
630
|
-
`;
|
|
631
|
-
}).join(',')}
|
|
632
|
-
}
|
|
654
|
+
import exposesMap from "${VIRTUAL_EXPOSES}"
|
|
633
655
|
import {usedShared, usedRemotes} from "${getLocalSharedImportMapPath()}"
|
|
634
656
|
import {
|
|
635
657
|
initResolve
|
|
@@ -639,7 +661,8 @@ function generateRemoteEntry(options) {
|
|
|
639
661
|
name: ${JSON.stringify(options.name)},
|
|
640
662
|
remotes: usedRemotes,
|
|
641
663
|
shared: usedShared,
|
|
642
|
-
plugins: [${pluginImportNames.map(item => `${item[0]}()`).join(', ')}]
|
|
664
|
+
plugins: [${pluginImportNames.map(item => `${item[0]}()`).join(', ')}],
|
|
665
|
+
${options.shareStrategy ? `shareStrategy: ${options.shareStrategy}` : ''}
|
|
643
666
|
});
|
|
644
667
|
initRes.initShareScopeMap('${options.shareScope}', shared);
|
|
645
668
|
initResolve(initRes)
|
|
@@ -660,7 +683,7 @@ function generateRemoteEntry(options) {
|
|
|
660
683
|
* Inject entry file, automatically init when used as host,
|
|
661
684
|
* and will not inject remoteEntry
|
|
662
685
|
*/
|
|
663
|
-
const hostAutoInitModule = new VirtualModule(
|
|
686
|
+
const hostAutoInitModule = new VirtualModule('hostAutoInit');
|
|
664
687
|
function writeHostAutoInit() {
|
|
665
688
|
hostAutoInitModule.writeSync(`
|
|
666
689
|
import {init} from "${REMOTE_ENTRY_ID}"
|
|
@@ -687,20 +710,19 @@ const Manifest = () => {
|
|
|
687
710
|
filename,
|
|
688
711
|
manifest: manifestOptions
|
|
689
712
|
} = mfOptions;
|
|
690
|
-
let mfManifestName =
|
|
713
|
+
let mfManifestName = '';
|
|
691
714
|
if (manifestOptions === true) {
|
|
692
|
-
mfManifestName =
|
|
715
|
+
mfManifestName = 'mf-manifest.json';
|
|
693
716
|
}
|
|
694
|
-
if (typeof manifestOptions !==
|
|
695
|
-
mfManifestName = join((manifestOptions == null ? void 0 : manifestOptions.filePath) ||
|
|
717
|
+
if (typeof manifestOptions !== 'boolean') {
|
|
718
|
+
mfManifestName = join((manifestOptions == null ? void 0 : manifestOptions.filePath) || '', (manifestOptions == null ? void 0 : manifestOptions.fileName) || '');
|
|
696
719
|
}
|
|
697
720
|
let extensions;
|
|
698
721
|
let root;
|
|
699
722
|
let remoteEntryFile;
|
|
700
|
-
let publicPath;
|
|
701
723
|
let _command;
|
|
702
724
|
return [{
|
|
703
|
-
name: '
|
|
725
|
+
name: 'module-federation-manifest',
|
|
704
726
|
apply: 'serve',
|
|
705
727
|
configureServer(server) {
|
|
706
728
|
server.middlewares.use((req, res, next) => {
|
|
@@ -708,10 +730,10 @@ const Manifest = () => {
|
|
|
708
730
|
next();
|
|
709
731
|
return;
|
|
710
732
|
}
|
|
711
|
-
if (req.url === mfManifestName.replace(/^\/?/,
|
|
733
|
+
if (req.url === mfManifestName.replace(/^\/?/, '/')) {
|
|
712
734
|
res.setHeader('Content-Type', 'application/json');
|
|
713
735
|
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
714
|
-
res.end(JSON.stringify({
|
|
736
|
+
res.end(JSON.stringify(_extends({}, generateMFManifest({}), {
|
|
715
737
|
id: name,
|
|
716
738
|
name: name,
|
|
717
739
|
metaData: {
|
|
@@ -736,70 +758,16 @@ const Manifest = () => {
|
|
|
736
758
|
name: ''
|
|
737
759
|
},
|
|
738
760
|
globalName: name,
|
|
739
|
-
pluginVersion: '0.2.5'
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
shared: Array.from(getUsedShares()).map(shareKey => {
|
|
743
|
-
const shareItem = getNormalizeShareItem(shareKey);
|
|
744
|
-
return {
|
|
745
|
-
id: `${name}:${shareKey}`,
|
|
746
|
-
name: shareKey,
|
|
747
|
-
version: shareItem.version,
|
|
748
|
-
requiredVersion: shareItem.shareConfig.requiredVersion,
|
|
749
|
-
assets: {
|
|
750
|
-
js: {
|
|
751
|
-
async: [],
|
|
752
|
-
sync: []
|
|
753
|
-
},
|
|
754
|
-
css: {
|
|
755
|
-
async: [],
|
|
756
|
-
sync: []
|
|
757
|
-
}
|
|
758
|
-
}
|
|
759
|
-
};
|
|
760
|
-
}),
|
|
761
|
-
remotes: function () {
|
|
762
|
-
const remotes = [];
|
|
763
|
-
const usedRemotesMap = getUsedRemotesMap();
|
|
764
|
-
Object.keys(usedRemotesMap).forEach(remoteKey => {
|
|
765
|
-
const usedModules = Array.from(usedRemotesMap[remoteKey]);
|
|
766
|
-
usedModules.forEach(moduleKey => {
|
|
767
|
-
remotes.push({
|
|
768
|
-
federationContainerName: mfOptions.remotes[remoteKey].entry,
|
|
769
|
-
moduleName: moduleKey.replace(remoteKey, '').replace('/', ''),
|
|
770
|
-
alias: remoteKey,
|
|
771
|
-
entry: '*'
|
|
772
|
-
});
|
|
773
|
-
});
|
|
774
|
-
});
|
|
775
|
-
return remotes;
|
|
776
|
-
}(),
|
|
777
|
-
exposes: Object.keys(mfOptions.exposes).map(key => {
|
|
778
|
-
const formatKey = key.replace('./', '');
|
|
779
|
-
return {
|
|
780
|
-
id: name + ':' + formatKey,
|
|
781
|
-
name: formatKey,
|
|
782
|
-
assets: {
|
|
783
|
-
js: {
|
|
784
|
-
async: [],
|
|
785
|
-
sync: []
|
|
786
|
-
},
|
|
787
|
-
css: {
|
|
788
|
-
sync: [],
|
|
789
|
-
async: []
|
|
790
|
-
}
|
|
791
|
-
},
|
|
792
|
-
path: key
|
|
793
|
-
};
|
|
794
|
-
})
|
|
795
|
-
}));
|
|
761
|
+
pluginVersion: '0.2.5'
|
|
762
|
+
}
|
|
763
|
+
})));
|
|
796
764
|
} else {
|
|
797
765
|
next();
|
|
798
766
|
}
|
|
799
767
|
});
|
|
800
768
|
}
|
|
801
769
|
}, {
|
|
802
|
-
name: '
|
|
770
|
+
name: 'module-federation-manifest',
|
|
803
771
|
enforce: 'post',
|
|
804
772
|
config(config, {
|
|
805
773
|
command
|
|
@@ -811,10 +779,10 @@ const Manifest = () => {
|
|
|
811
779
|
configResolved(config) {
|
|
812
780
|
root = config.root;
|
|
813
781
|
extensions = config.resolve.extensions || ['.mjs', '.js', '.mts', '.ts', '.jsx', '.tsx', '.json'];
|
|
814
|
-
|
|
815
|
-
if (_command ===
|
|
782
|
+
config.base ? config.base.replace(/\/?$/, '/') : 'auto';
|
|
783
|
+
if (_command === 'serve') {
|
|
816
784
|
const origin = config.server.origin;
|
|
817
|
-
|
|
785
|
+
origin ? origin.replace(/\/?$/, '/') : 'auto';
|
|
818
786
|
}
|
|
819
787
|
},
|
|
820
788
|
async generateBundle(options, bundle) {
|
|
@@ -835,7 +803,7 @@ const Manifest = () => {
|
|
|
835
803
|
};
|
|
836
804
|
// 遍历打包生成的每个文件
|
|
837
805
|
for (const [fileName, fileData] of Object.entries(bundle)) {
|
|
838
|
-
if (mfOptions.filename.replace(/[\[\]]/g,
|
|
806
|
+
if (mfOptions.filename.replace(/[\[\]]/g, '_') === fileData.name || fileData.name === 'remoteEntry') {
|
|
839
807
|
remoteEntryFile = fileData.fileName;
|
|
840
808
|
}
|
|
841
809
|
if (fileData.type === 'chunk') {
|
|
@@ -845,7 +813,7 @@ const Manifest = () => {
|
|
|
845
813
|
const relativeModulePath = relative(root, modulePath);
|
|
846
814
|
// 检查模块是否在 preloadModules 列表中
|
|
847
815
|
for (const preloadModule of exposesModules) {
|
|
848
|
-
const formatPreloadModule = preloadModule.replace(
|
|
816
|
+
const formatPreloadModule = preloadModule.replace('./', '');
|
|
849
817
|
if (isModuleMatched(relativeModulePath, formatPreloadModule)) {
|
|
850
818
|
if (!filesContainingModules[preloadModule]) {
|
|
851
819
|
filesContainingModules[preloadModule] = {
|
|
@@ -878,7 +846,7 @@ const Manifest = () => {
|
|
|
878
846
|
}
|
|
879
847
|
const fileToShareKey = {};
|
|
880
848
|
await Promise.all(Array.from(getUsedShares()).map(async shareKey => {
|
|
881
|
-
const file = (await this.resolve(getPreBuildLibImportId(shareKey))).id.split(
|
|
849
|
+
const file = (await this.resolve(getPreBuildLibImportId(shareKey))).id.split('?')[0];
|
|
882
850
|
fileToShareKey[file] = shareKey;
|
|
883
851
|
}));
|
|
884
852
|
// 遍历打包生成的每个文件
|
|
@@ -909,7 +877,7 @@ const Manifest = () => {
|
|
|
909
877
|
this.emitFile({
|
|
910
878
|
type: 'asset',
|
|
911
879
|
fileName: mfManifestName,
|
|
912
|
-
source: generateMFManifest(filesContainingModules)
|
|
880
|
+
source: JSON.stringify(generateMFManifest(filesContainingModules))
|
|
913
881
|
});
|
|
914
882
|
}
|
|
915
883
|
}];
|
|
@@ -938,8 +906,7 @@ const Manifest = () => {
|
|
|
938
906
|
});
|
|
939
907
|
// @ts-ignore
|
|
940
908
|
const shared = Array.from(getUsedShares()).map(shareKey => {
|
|
941
|
-
|
|
942
|
-
if (!preloadMap[shareKey]) return;
|
|
909
|
+
var _preloadMap$shareKey, _preloadMap$shareKey2;
|
|
943
910
|
const shareItem = getNormalizeShareItem(shareKey);
|
|
944
911
|
return {
|
|
945
912
|
id: `${name}:${shareKey}`,
|
|
@@ -948,8 +915,8 @@ const Manifest = () => {
|
|
|
948
915
|
requiredVersion: shareItem.shareConfig.requiredVersion,
|
|
949
916
|
assets: {
|
|
950
917
|
js: {
|
|
951
|
-
async: preloadMap[shareKey].async,
|
|
952
|
-
sync: preloadMap[shareKey].sync
|
|
918
|
+
async: (preloadMap == null || (_preloadMap$shareKey = preloadMap[shareKey]) == null ? void 0 : _preloadMap$shareKey.async) || [],
|
|
919
|
+
sync: (preloadMap == null || (_preloadMap$shareKey2 = preloadMap[shareKey]) == null ? void 0 : _preloadMap$shareKey2.sync) || []
|
|
953
920
|
},
|
|
954
921
|
css: {
|
|
955
922
|
async: [],
|
|
@@ -959,17 +926,17 @@ const Manifest = () => {
|
|
|
959
926
|
};
|
|
960
927
|
}).filter(item => item);
|
|
961
928
|
const exposes = Object.keys(options.exposes).map(key => {
|
|
929
|
+
var _preloadMap$sourceFil, _preloadMap$sourceFil2;
|
|
962
930
|
// assets(.css, .jpg, .svg等)其他资源, 不重要, 暂未处理
|
|
963
931
|
const formatKey = key.replace('./', '');
|
|
964
932
|
const sourceFile = options.exposes[key].import;
|
|
965
|
-
if (!preloadMap[sourceFile]) return;
|
|
966
933
|
return {
|
|
967
934
|
id: name + ':' + formatKey,
|
|
968
935
|
name: formatKey,
|
|
969
936
|
assets: {
|
|
970
937
|
js: {
|
|
971
|
-
async: preloadMap[sourceFile].async,
|
|
972
|
-
sync: preloadMap[sourceFile].sync
|
|
938
|
+
async: (preloadMap == null || (_preloadMap$sourceFil = preloadMap[sourceFile]) == null ? void 0 : _preloadMap$sourceFil.async) || [],
|
|
939
|
+
sync: (preloadMap == null || (_preloadMap$sourceFil2 = preloadMap[sourceFile]) == null ? void 0 : _preloadMap$sourceFil2.sync) || []
|
|
973
940
|
},
|
|
974
941
|
css: {
|
|
975
942
|
sync: [],
|
|
@@ -998,14 +965,13 @@ const Manifest = () => {
|
|
|
998
965
|
// "api": "@mf-types.d.ts"
|
|
999
966
|
},
|
|
1000
967
|
globalName: name,
|
|
1001
|
-
pluginVersion: '0.2.5'
|
|
1002
|
-
publicPath
|
|
968
|
+
pluginVersion: '0.2.5'
|
|
1003
969
|
},
|
|
1004
970
|
shared,
|
|
1005
971
|
remotes,
|
|
1006
972
|
exposes
|
|
1007
973
|
};
|
|
1008
|
-
return
|
|
974
|
+
return result;
|
|
1009
975
|
}
|
|
1010
976
|
};
|
|
1011
977
|
|
|
@@ -1014,20 +980,21 @@ let _resolve,
|
|
|
1014
980
|
_resolve = resolve;
|
|
1015
981
|
});
|
|
1016
982
|
let parsePromise = promise;
|
|
983
|
+
let exposesParseEnd = false;
|
|
1017
984
|
const parseStartSet = new Set();
|
|
1018
985
|
const parseEndSet = new Set();
|
|
1019
986
|
function pluginModuleParseEnd (excludeFn) {
|
|
1020
987
|
return [{
|
|
1021
|
-
name:
|
|
1022
|
-
apply:
|
|
988
|
+
name: '_',
|
|
989
|
+
apply: 'serve',
|
|
1023
990
|
config() {
|
|
1024
991
|
// No waiting in development mode
|
|
1025
992
|
_resolve(1);
|
|
1026
993
|
}
|
|
1027
994
|
}, {
|
|
1028
|
-
enforce:
|
|
1029
|
-
name:
|
|
1030
|
-
apply:
|
|
995
|
+
enforce: 'pre',
|
|
996
|
+
name: 'parseStart',
|
|
997
|
+
apply: 'build',
|
|
1031
998
|
load(id) {
|
|
1032
999
|
if (excludeFn(id)) {
|
|
1033
1000
|
return;
|
|
@@ -1035,16 +1002,20 @@ function pluginModuleParseEnd (excludeFn) {
|
|
|
1035
1002
|
parseStartSet.add(id);
|
|
1036
1003
|
}
|
|
1037
1004
|
}, {
|
|
1038
|
-
enforce:
|
|
1039
|
-
name:
|
|
1040
|
-
apply:
|
|
1005
|
+
enforce: 'post',
|
|
1006
|
+
name: 'parseEnd',
|
|
1007
|
+
apply: 'build',
|
|
1041
1008
|
moduleParsed(module) {
|
|
1042
1009
|
const id = module.id;
|
|
1043
1010
|
if (excludeFn(id)) {
|
|
1044
1011
|
return;
|
|
1045
1012
|
}
|
|
1013
|
+
if (id === VIRTUAL_EXPOSES) {
|
|
1014
|
+
// When the entry JS file is empty and only contains exposes export code, it’s necessary to wait for the exposes modules to be resolved in order to collect the dependencies being used.
|
|
1015
|
+
exposesParseEnd = true;
|
|
1016
|
+
}
|
|
1046
1017
|
parseEndSet.add(id);
|
|
1047
|
-
if (parseStartSet.size === parseEndSet.size) {
|
|
1018
|
+
if (exposesParseEnd && parseStartSet.size === parseEndSet.size) {
|
|
1048
1019
|
_resolve(1);
|
|
1049
1020
|
}
|
|
1050
1021
|
}
|
|
@@ -1060,17 +1031,26 @@ function pluginProxyRemoteEntry () {
|
|
|
1060
1031
|
if (id === REMOTE_ENTRY_ID) {
|
|
1061
1032
|
return REMOTE_ENTRY_ID;
|
|
1062
1033
|
}
|
|
1034
|
+
if (id === VIRTUAL_EXPOSES) {
|
|
1035
|
+
return VIRTUAL_EXPOSES;
|
|
1036
|
+
}
|
|
1063
1037
|
},
|
|
1064
1038
|
load(id) {
|
|
1065
1039
|
if (id === REMOTE_ENTRY_ID) {
|
|
1066
1040
|
return parsePromise.then(_ => generateRemoteEntry(getNormalizeModuleFederationOptions()));
|
|
1067
1041
|
}
|
|
1042
|
+
if (id === VIRTUAL_EXPOSES) {
|
|
1043
|
+
return generateExposes();
|
|
1044
|
+
}
|
|
1068
1045
|
},
|
|
1069
1046
|
async transform(code, id) {
|
|
1070
1047
|
if (!filter(id)) return;
|
|
1071
1048
|
if (id.includes(REMOTE_ENTRY_ID)) {
|
|
1072
1049
|
return parsePromise.then(_ => generateRemoteEntry(getNormalizeModuleFederationOptions()));
|
|
1073
1050
|
}
|
|
1051
|
+
if (id === VIRTUAL_EXPOSES) {
|
|
1052
|
+
return generateExposes();
|
|
1053
|
+
}
|
|
1074
1054
|
}
|
|
1075
1055
|
};
|
|
1076
1056
|
}
|
|
@@ -1081,7 +1061,7 @@ function pluginProxyRemotes (options) {
|
|
|
1081
1061
|
remotes
|
|
1082
1062
|
} = options;
|
|
1083
1063
|
return {
|
|
1084
|
-
name:
|
|
1064
|
+
name: 'proxyRemotes',
|
|
1085
1065
|
config(config, {
|
|
1086
1066
|
command: _command
|
|
1087
1067
|
}) {
|
|
@@ -1089,7 +1069,7 @@ function pluginProxyRemotes (options) {
|
|
|
1089
1069
|
const remote = remotes[key];
|
|
1090
1070
|
config.resolve.alias.push({
|
|
1091
1071
|
find: new RegExp(`^(${remote.name}(\/.*|$))`),
|
|
1092
|
-
replacement:
|
|
1072
|
+
replacement: '$1',
|
|
1093
1073
|
customResolver(source) {
|
|
1094
1074
|
const remoteModule = getRemoteVirtualModule(source, _command);
|
|
1095
1075
|
addUsedRemote(remote.name, source);
|
|
@@ -1143,8 +1123,8 @@ function proxySharedModule(options) {
|
|
|
1143
1123
|
} = options;
|
|
1144
1124
|
let _config;
|
|
1145
1125
|
return [{
|
|
1146
|
-
name:
|
|
1147
|
-
enforce:
|
|
1126
|
+
name: 'generateLocalSharedImportMap',
|
|
1127
|
+
enforce: 'post',
|
|
1148
1128
|
load(id) {
|
|
1149
1129
|
if (id.includes(getLocalSharedImportMapPath())) {
|
|
1150
1130
|
return parsePromise.then(_ => generateLocalSharedImportMap());
|
|
@@ -1165,11 +1145,11 @@ function proxySharedModule(options) {
|
|
|
1165
1145
|
command
|
|
1166
1146
|
}) {
|
|
1167
1147
|
config.resolve.alias.push(...Object.keys(shared).map(key => {
|
|
1168
|
-
const pattern = key.endsWith(
|
|
1148
|
+
const pattern = key.endsWith('/') ? `(^${key.replace(/\/$/, '')}(\/.+)?$)` : `(^${key}$)`;
|
|
1169
1149
|
return {
|
|
1170
1150
|
// Intercept all shared requests and proxy them to loadShare
|
|
1171
1151
|
find: new RegExp(pattern),
|
|
1172
|
-
replacement:
|
|
1152
|
+
replacement: '$1',
|
|
1173
1153
|
customResolver(source, importer) {
|
|
1174
1154
|
if (/\.css$/.test(source)) return;
|
|
1175
1155
|
const loadSharePath = getLoadShareModulePath(source);
|
|
@@ -1183,7 +1163,7 @@ function proxySharedModule(options) {
|
|
|
1183
1163
|
}));
|
|
1184
1164
|
const savePrebuild = new PromiseStore();
|
|
1185
1165
|
config.resolve.alias.push(...Object.keys(shared).map(key => {
|
|
1186
|
-
return command ===
|
|
1166
|
+
return command === 'build' ? {
|
|
1187
1167
|
find: new RegExp(`(.*${PREBUILD_TAG}.*)`),
|
|
1188
1168
|
replacement: function ($1) {
|
|
1189
1169
|
const pkgName = VirtualModule.findModule(PREBUILD_TAG, $1).name;
|
|
@@ -1191,7 +1171,7 @@ function proxySharedModule(options) {
|
|
|
1191
1171
|
}
|
|
1192
1172
|
} : {
|
|
1193
1173
|
find: new RegExp(`(.*${PREBUILD_TAG}.*)`),
|
|
1194
|
-
replacement:
|
|
1174
|
+
replacement: '$1',
|
|
1195
1175
|
async customResolver(source, importer) {
|
|
1196
1176
|
const pkgName = VirtualModule.findModule(PREBUILD_TAG, source).name;
|
|
1197
1177
|
const result = await this.resolve(pkgName).then(item => item.id);
|
|
@@ -1206,8 +1186,8 @@ function proxySharedModule(options) {
|
|
|
1206
1186
|
}));
|
|
1207
1187
|
}
|
|
1208
1188
|
}, {
|
|
1209
|
-
name:
|
|
1210
|
-
apply:
|
|
1189
|
+
name: 'watchLocalSharedImportMap',
|
|
1190
|
+
apply: 'serve',
|
|
1211
1191
|
config(config) {
|
|
1212
1192
|
config.optimizeDeps = defu(config.optimizeDeps, {
|
|
1213
1193
|
exclude: [getLocalSharedImportMapPath()]
|
|
@@ -1271,7 +1251,7 @@ function federation(mfUserOptions) {
|
|
|
1271
1251
|
shared,
|
|
1272
1252
|
filename
|
|
1273
1253
|
} = options;
|
|
1274
|
-
if (!name) throw new Error(
|
|
1254
|
+
if (!name) throw new Error('name is required');
|
|
1275
1255
|
return [aliasToArrayPlugin, normalizeOptimizeDepsPlugin, ...addEntry({
|
|
1276
1256
|
entryName: 'remoteEntry',
|
|
1277
1257
|
entryPath: REMOTE_ENTRY_ID,
|
|
@@ -1279,6 +1259,9 @@ function federation(mfUserOptions) {
|
|
|
1279
1259
|
}), ...addEntry({
|
|
1280
1260
|
entryName: 'hostInit',
|
|
1281
1261
|
entryPath: getHostAutoInitPath()
|
|
1262
|
+
}), ...addEntry({
|
|
1263
|
+
entryName: 'virtualExposes',
|
|
1264
|
+
entryPath: VIRTUAL_EXPOSES
|
|
1282
1265
|
}), pluginProxyRemoteEntry(), pluginProxyRemotes(options), ...pluginModuleParseEnd(id => {
|
|
1283
1266
|
return id.includes(getHostAutoInitImportId()) || id.includes(REMOTE_ENTRY_ID) || id.includes(getLocalSharedImportMapPath());
|
|
1284
1267
|
}), ...proxySharedModule({
|
|
@@ -1290,6 +1273,7 @@ function federation(mfUserOptions) {
|
|
|
1290
1273
|
command: _command
|
|
1291
1274
|
}) {
|
|
1292
1275
|
var _config$optimizeDeps;
|
|
1276
|
+
// TODO: singleton
|
|
1293
1277
|
config.resolve.alias.push({
|
|
1294
1278
|
find: '@module-federation/runtime',
|
|
1295
1279
|
replacement: require.resolve('@module-federation/runtime')
|