@module-federation/vite 1.14.2 → 1.14.3
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/lib/index.cjs +87 -14
- package/lib/index.mjs +87 -14
- package/package.json +4 -4
package/lib/index.cjs
CHANGED
|
@@ -1239,6 +1239,16 @@ function generateExposes(options) {
|
|
|
1239
1239
|
return `
|
|
1240
1240
|
const cssAssetMap = ${JSON.stringify(options.bundleAllCSS ? EXPOSES_CSS_MAP_PLACEHOLDER : {})};
|
|
1241
1241
|
const injectedCssHrefs = new Set();
|
|
1242
|
+
let exposeLoadQueue = Promise.resolve();
|
|
1243
|
+
|
|
1244
|
+
async function importExposedModule(loader) {
|
|
1245
|
+
const currentLoad = exposeLoadQueue.then(loader, loader);
|
|
1246
|
+
exposeLoadQueue = currentLoad.then(
|
|
1247
|
+
() => undefined,
|
|
1248
|
+
() => undefined
|
|
1249
|
+
);
|
|
1250
|
+
return currentLoad;
|
|
1251
|
+
}
|
|
1242
1252
|
|
|
1243
1253
|
async function injectCssAssets(exposeKey) {
|
|
1244
1254
|
if (typeof document === "undefined") {
|
|
@@ -1283,7 +1293,9 @@ function generateExposes(options) {
|
|
|
1283
1293
|
return `
|
|
1284
1294
|
${JSON.stringify(key)}: async () => {
|
|
1285
1295
|
await injectCssAssets(${JSON.stringify(key)})
|
|
1286
|
-
const importModule = await
|
|
1296
|
+
const importModule = await importExposedModule(
|
|
1297
|
+
() => import(${JSON.stringify(options.exposes[key].import)})
|
|
1298
|
+
)
|
|
1287
1299
|
const exportModule = {}
|
|
1288
1300
|
Object.assign(exportModule, importModule)
|
|
1289
1301
|
Object.defineProperty(exportModule, "__esModule", {
|
|
@@ -2619,6 +2631,37 @@ var PromiseStore = class {
|
|
|
2619
2631
|
function getPrebuildResolutionSource(pkgName, shareItem) {
|
|
2620
2632
|
return getConcreteSharedImportSource(pkgName, shareItem) || pkgName;
|
|
2621
2633
|
}
|
|
2634
|
+
/**
|
|
2635
|
+
* Reads the dependencies of an installed package from its package.json.
|
|
2636
|
+
*/
|
|
2637
|
+
function getPackageDependencies(pkg) {
|
|
2638
|
+
const packageName = removePathFromNpmPackage(pkg);
|
|
2639
|
+
const cwd = getPackageDetectionCwd();
|
|
2640
|
+
const candidates = [pathe.default.join(cwd, "node_modules", packageName, "package.json")];
|
|
2641
|
+
for (const candidate of candidates) if ((0, fs.existsSync)(candidate)) try {
|
|
2642
|
+
const json = JSON.parse((0, fs.readFileSync)(candidate, "utf-8"));
|
|
2643
|
+
return Object.keys(json.dependencies || {});
|
|
2644
|
+
} catch {}
|
|
2645
|
+
return [];
|
|
2646
|
+
}
|
|
2647
|
+
/**
|
|
2648
|
+
* In dev mode, detects shared packages that are sub-dependencies of other
|
|
2649
|
+
* shared packages and removes them to avoid initialization order issues.
|
|
2650
|
+
* For example, `lit` depends on `lit-html`, `lit-element`, and
|
|
2651
|
+
* `@lit/reactive-element` — sharing them separately causes the child modules
|
|
2652
|
+
* to load before their parent, resulting in `undefined` class extends errors.
|
|
2653
|
+
*/
|
|
2654
|
+
function excludeSharedSubDependencies(shared) {
|
|
2655
|
+
const sharedKeys = new Set(Object.keys(shared));
|
|
2656
|
+
for (const parentKey of sharedKeys) {
|
|
2657
|
+
const deps = getPackageDependencies(parentKey);
|
|
2658
|
+
for (const dep of deps) if (sharedKeys.has(dep) && dep !== parentKey) {
|
|
2659
|
+
mfWarn(`"${dep}" is a dependency of shared package "${parentKey}" and is also shared separately. This may cause initialization order issues in dev mode. Consider sharing only "${parentKey}".\n Auto-excluding "${dep}" from shared modules for dev mode.`);
|
|
2660
|
+
delete shared[dep];
|
|
2661
|
+
sharedKeys.delete(dep);
|
|
2662
|
+
}
|
|
2663
|
+
}
|
|
2664
|
+
}
|
|
2622
2665
|
function proxySharedModule(options) {
|
|
2623
2666
|
const { shared = {} } = options;
|
|
2624
2667
|
let _config;
|
|
@@ -2644,6 +2687,7 @@ function proxySharedModule(options) {
|
|
|
2644
2687
|
const isRolldown = getIsRolldown(this);
|
|
2645
2688
|
_command = command;
|
|
2646
2689
|
useDirectReactImport = isVinext || isAstro;
|
|
2690
|
+
if (command === "serve") excludeSharedSubDependencies(shared);
|
|
2647
2691
|
config.resolve.alias.push(...Object.keys(shared).filter((key) => !(useDirectReactImport && key === "react")).map((key) => {
|
|
2648
2692
|
const keyBase = key.endsWith("/") ? key.slice(0, -1) : key;
|
|
2649
2693
|
const escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -3241,6 +3285,44 @@ function escapeUnsafeJsSourceChars(str) {
|
|
|
3241
3285
|
return UNSAFE_JS_SOURCE_CHAR_MAP[char] ?? char;
|
|
3242
3286
|
});
|
|
3243
3287
|
}
|
|
3288
|
+
function insertAfterLastTopLevelImport(code, snippet) {
|
|
3289
|
+
let cursor = 0;
|
|
3290
|
+
let lastImportEnd = -1;
|
|
3291
|
+
const skipTrivia = () => {
|
|
3292
|
+
while (cursor < code.length) {
|
|
3293
|
+
if (/\s/.test(code[cursor])) {
|
|
3294
|
+
cursor++;
|
|
3295
|
+
continue;
|
|
3296
|
+
}
|
|
3297
|
+
if (code.startsWith("//", cursor)) {
|
|
3298
|
+
const lineEnd = code.indexOf("\n", cursor);
|
|
3299
|
+
cursor = lineEnd === -1 ? code.length : lineEnd + 1;
|
|
3300
|
+
continue;
|
|
3301
|
+
}
|
|
3302
|
+
if (code.startsWith("/*", cursor)) {
|
|
3303
|
+
const commentEnd = code.indexOf("*/", cursor + 2);
|
|
3304
|
+
cursor = commentEnd === -1 ? code.length : commentEnd + 2;
|
|
3305
|
+
continue;
|
|
3306
|
+
}
|
|
3307
|
+
break;
|
|
3308
|
+
}
|
|
3309
|
+
};
|
|
3310
|
+
while (cursor < code.length) {
|
|
3311
|
+
skipTrivia();
|
|
3312
|
+
if (!code.startsWith("import", cursor) || !/[\s"'*{]/.test(code[cursor + 6] ?? "")) break;
|
|
3313
|
+
const statementEnd = code.indexOf(";", cursor);
|
|
3314
|
+
if (statementEnd !== -1) {
|
|
3315
|
+
lastImportEnd = statementEnd + 1;
|
|
3316
|
+
cursor = statementEnd + 1;
|
|
3317
|
+
continue;
|
|
3318
|
+
}
|
|
3319
|
+
const lineEnd = code.indexOf("\n", cursor);
|
|
3320
|
+
lastImportEnd = lineEnd === -1 ? code.length : lineEnd + 1;
|
|
3321
|
+
cursor = lastImportEnd;
|
|
3322
|
+
}
|
|
3323
|
+
if (lastImportEnd === -1) return;
|
|
3324
|
+
return code.slice(0, lastImportEnd) + snippet + code.slice(lastImportEnd);
|
|
3325
|
+
}
|
|
3244
3326
|
/**
|
|
3245
3327
|
* Plugin that runs FIRST to create virtual module files in the config hook.
|
|
3246
3328
|
* This prevents 504 "Outdated Optimize Dep" errors by ensuring files exist
|
|
@@ -3475,11 +3557,9 @@ function federation(mfUserOptions) {
|
|
|
3475
3557
|
for (const v of importedFromLoadShare) if (new RegExp("\\(" + v + "\\(\\)\\s*,\\s*\\w+\\(\\w+\\)\\)").test(code)) allInits.push(v);
|
|
3476
3558
|
if (allInits.length === 0) continue;
|
|
3477
3559
|
const awaits = allInits.map((v) => `await ${v}();`).join("");
|
|
3478
|
-
const
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
if (lastFromEnd !== -1) {
|
|
3482
|
-
chunk.code = code.slice(0, lastFromEnd) + awaits + code.slice(lastFromEnd);
|
|
3560
|
+
const codeWithAwaits = insertAfterLastTopLevelImport(code, awaits);
|
|
3561
|
+
if (codeWithAwaits) {
|
|
3562
|
+
chunk.code = codeWithAwaits;
|
|
3483
3563
|
continue;
|
|
3484
3564
|
}
|
|
3485
3565
|
const exportIdx = code.search(/\bexport\s*[{d]/);
|
|
@@ -3610,14 +3690,7 @@ function federation(mfUserOptions) {
|
|
|
3610
3690
|
})) return;
|
|
3611
3691
|
if (/await\s+init_\w+__loadShare__/.test(code)) return;
|
|
3612
3692
|
if (code.includes("__esmMin")) return;
|
|
3613
|
-
|
|
3614
|
-
const topLevelImportRe = /^import\s/gm;
|
|
3615
|
-
let lastImportIdx = -1;
|
|
3616
|
-
let importMatch;
|
|
3617
|
-
while ((importMatch = topLevelImportRe.exec(code)) !== null) lastImportIdx = importMatch.index;
|
|
3618
|
-
if (lastImportIdx === -1) return;
|
|
3619
|
-
const lineEnd = code.indexOf("\n", lastImportIdx);
|
|
3620
|
-
return code.slice(0, lineEnd + 1) + awaits + "\n" + code.slice(lineEnd + 1);
|
|
3693
|
+
return insertAfterLastTopLevelImport(code, [...initFns].map((fn) => `await ${fn}();`).join("\n") + "\n");
|
|
3621
3694
|
}
|
|
3622
3695
|
},
|
|
3623
3696
|
PluginDevProxyModuleTopLevelAwait(),
|
package/lib/index.mjs
CHANGED
|
@@ -1216,6 +1216,16 @@ function generateExposes(options) {
|
|
|
1216
1216
|
return `
|
|
1217
1217
|
const cssAssetMap = ${JSON.stringify(options.bundleAllCSS ? EXPOSES_CSS_MAP_PLACEHOLDER : {})};
|
|
1218
1218
|
const injectedCssHrefs = new Set();
|
|
1219
|
+
let exposeLoadQueue = Promise.resolve();
|
|
1220
|
+
|
|
1221
|
+
async function importExposedModule(loader) {
|
|
1222
|
+
const currentLoad = exposeLoadQueue.then(loader, loader);
|
|
1223
|
+
exposeLoadQueue = currentLoad.then(
|
|
1224
|
+
() => undefined,
|
|
1225
|
+
() => undefined
|
|
1226
|
+
);
|
|
1227
|
+
return currentLoad;
|
|
1228
|
+
}
|
|
1219
1229
|
|
|
1220
1230
|
async function injectCssAssets(exposeKey) {
|
|
1221
1231
|
if (typeof document === "undefined") {
|
|
@@ -1260,7 +1270,9 @@ function generateExposes(options) {
|
|
|
1260
1270
|
return `
|
|
1261
1271
|
${JSON.stringify(key)}: async () => {
|
|
1262
1272
|
await injectCssAssets(${JSON.stringify(key)})
|
|
1263
|
-
const importModule = await
|
|
1273
|
+
const importModule = await importExposedModule(
|
|
1274
|
+
() => import(${JSON.stringify(options.exposes[key].import)})
|
|
1275
|
+
)
|
|
1264
1276
|
const exportModule = {}
|
|
1265
1277
|
Object.assign(exportModule, importModule)
|
|
1266
1278
|
Object.defineProperty(exportModule, "__esModule", {
|
|
@@ -2596,6 +2608,37 @@ var PromiseStore = class {
|
|
|
2596
2608
|
function getPrebuildResolutionSource(pkgName, shareItem) {
|
|
2597
2609
|
return getConcreteSharedImportSource(pkgName, shareItem) || pkgName;
|
|
2598
2610
|
}
|
|
2611
|
+
/**
|
|
2612
|
+
* Reads the dependencies of an installed package from its package.json.
|
|
2613
|
+
*/
|
|
2614
|
+
function getPackageDependencies(pkg) {
|
|
2615
|
+
const packageName = removePathFromNpmPackage(pkg);
|
|
2616
|
+
const cwd = getPackageDetectionCwd();
|
|
2617
|
+
const candidates = [path.join(cwd, "node_modules", packageName, "package.json")];
|
|
2618
|
+
for (const candidate of candidates) if (existsSync(candidate)) try {
|
|
2619
|
+
const json = JSON.parse(readFileSync(candidate, "utf-8"));
|
|
2620
|
+
return Object.keys(json.dependencies || {});
|
|
2621
|
+
} catch {}
|
|
2622
|
+
return [];
|
|
2623
|
+
}
|
|
2624
|
+
/**
|
|
2625
|
+
* In dev mode, detects shared packages that are sub-dependencies of other
|
|
2626
|
+
* shared packages and removes them to avoid initialization order issues.
|
|
2627
|
+
* For example, `lit` depends on `lit-html`, `lit-element`, and
|
|
2628
|
+
* `@lit/reactive-element` — sharing them separately causes the child modules
|
|
2629
|
+
* to load before their parent, resulting in `undefined` class extends errors.
|
|
2630
|
+
*/
|
|
2631
|
+
function excludeSharedSubDependencies(shared) {
|
|
2632
|
+
const sharedKeys = new Set(Object.keys(shared));
|
|
2633
|
+
for (const parentKey of sharedKeys) {
|
|
2634
|
+
const deps = getPackageDependencies(parentKey);
|
|
2635
|
+
for (const dep of deps) if (sharedKeys.has(dep) && dep !== parentKey) {
|
|
2636
|
+
mfWarn(`"${dep}" is a dependency of shared package "${parentKey}" and is also shared separately. This may cause initialization order issues in dev mode. Consider sharing only "${parentKey}".\n Auto-excluding "${dep}" from shared modules for dev mode.`);
|
|
2637
|
+
delete shared[dep];
|
|
2638
|
+
sharedKeys.delete(dep);
|
|
2639
|
+
}
|
|
2640
|
+
}
|
|
2641
|
+
}
|
|
2599
2642
|
function proxySharedModule(options) {
|
|
2600
2643
|
const { shared = {} } = options;
|
|
2601
2644
|
let _config;
|
|
@@ -2621,6 +2664,7 @@ function proxySharedModule(options) {
|
|
|
2621
2664
|
const isRolldown = getIsRolldown(this);
|
|
2622
2665
|
_command = command;
|
|
2623
2666
|
useDirectReactImport = isVinext || isAstro;
|
|
2667
|
+
if (command === "serve") excludeSharedSubDependencies(shared);
|
|
2624
2668
|
config.resolve.alias.push(...Object.keys(shared).filter((key) => !(useDirectReactImport && key === "react")).map((key) => {
|
|
2625
2669
|
const keyBase = key.endsWith("/") ? key.slice(0, -1) : key;
|
|
2626
2670
|
const escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -3218,6 +3262,44 @@ function escapeUnsafeJsSourceChars(str) {
|
|
|
3218
3262
|
return UNSAFE_JS_SOURCE_CHAR_MAP[char] ?? char;
|
|
3219
3263
|
});
|
|
3220
3264
|
}
|
|
3265
|
+
function insertAfterLastTopLevelImport(code, snippet) {
|
|
3266
|
+
let cursor = 0;
|
|
3267
|
+
let lastImportEnd = -1;
|
|
3268
|
+
const skipTrivia = () => {
|
|
3269
|
+
while (cursor < code.length) {
|
|
3270
|
+
if (/\s/.test(code[cursor])) {
|
|
3271
|
+
cursor++;
|
|
3272
|
+
continue;
|
|
3273
|
+
}
|
|
3274
|
+
if (code.startsWith("//", cursor)) {
|
|
3275
|
+
const lineEnd = code.indexOf("\n", cursor);
|
|
3276
|
+
cursor = lineEnd === -1 ? code.length : lineEnd + 1;
|
|
3277
|
+
continue;
|
|
3278
|
+
}
|
|
3279
|
+
if (code.startsWith("/*", cursor)) {
|
|
3280
|
+
const commentEnd = code.indexOf("*/", cursor + 2);
|
|
3281
|
+
cursor = commentEnd === -1 ? code.length : commentEnd + 2;
|
|
3282
|
+
continue;
|
|
3283
|
+
}
|
|
3284
|
+
break;
|
|
3285
|
+
}
|
|
3286
|
+
};
|
|
3287
|
+
while (cursor < code.length) {
|
|
3288
|
+
skipTrivia();
|
|
3289
|
+
if (!code.startsWith("import", cursor) || !/[\s"'*{]/.test(code[cursor + 6] ?? "")) break;
|
|
3290
|
+
const statementEnd = code.indexOf(";", cursor);
|
|
3291
|
+
if (statementEnd !== -1) {
|
|
3292
|
+
lastImportEnd = statementEnd + 1;
|
|
3293
|
+
cursor = statementEnd + 1;
|
|
3294
|
+
continue;
|
|
3295
|
+
}
|
|
3296
|
+
const lineEnd = code.indexOf("\n", cursor);
|
|
3297
|
+
lastImportEnd = lineEnd === -1 ? code.length : lineEnd + 1;
|
|
3298
|
+
cursor = lastImportEnd;
|
|
3299
|
+
}
|
|
3300
|
+
if (lastImportEnd === -1) return;
|
|
3301
|
+
return code.slice(0, lastImportEnd) + snippet + code.slice(lastImportEnd);
|
|
3302
|
+
}
|
|
3221
3303
|
/**
|
|
3222
3304
|
* Plugin that runs FIRST to create virtual module files in the config hook.
|
|
3223
3305
|
* This prevents 504 "Outdated Optimize Dep" errors by ensuring files exist
|
|
@@ -3452,11 +3534,9 @@ function federation(mfUserOptions) {
|
|
|
3452
3534
|
for (const v of importedFromLoadShare) if (new RegExp("\\(" + v + "\\(\\)\\s*,\\s*\\w+\\(\\w+\\)\\)").test(code)) allInits.push(v);
|
|
3453
3535
|
if (allInits.length === 0) continue;
|
|
3454
3536
|
const awaits = allInits.map((v) => `await ${v}();`).join("");
|
|
3455
|
-
const
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
if (lastFromEnd !== -1) {
|
|
3459
|
-
chunk.code = code.slice(0, lastFromEnd) + awaits + code.slice(lastFromEnd);
|
|
3537
|
+
const codeWithAwaits = insertAfterLastTopLevelImport(code, awaits);
|
|
3538
|
+
if (codeWithAwaits) {
|
|
3539
|
+
chunk.code = codeWithAwaits;
|
|
3460
3540
|
continue;
|
|
3461
3541
|
}
|
|
3462
3542
|
const exportIdx = code.search(/\bexport\s*[{d]/);
|
|
@@ -3587,14 +3667,7 @@ function federation(mfUserOptions) {
|
|
|
3587
3667
|
})) return;
|
|
3588
3668
|
if (/await\s+init_\w+__loadShare__/.test(code)) return;
|
|
3589
3669
|
if (code.includes("__esmMin")) return;
|
|
3590
|
-
|
|
3591
|
-
const topLevelImportRe = /^import\s/gm;
|
|
3592
|
-
let lastImportIdx = -1;
|
|
3593
|
-
let importMatch;
|
|
3594
|
-
while ((importMatch = topLevelImportRe.exec(code)) !== null) lastImportIdx = importMatch.index;
|
|
3595
|
-
if (lastImportIdx === -1) return;
|
|
3596
|
-
const lineEnd = code.indexOf("\n", lastImportIdx);
|
|
3597
|
-
return code.slice(0, lineEnd + 1) + awaits + "\n" + code.slice(lineEnd + 1);
|
|
3670
|
+
return insertAfterLastTopLevelImport(code, [...initFns].map((fn) => `await ${fn}();`).join("\n") + "\n");
|
|
3598
3671
|
}
|
|
3599
3672
|
},
|
|
3600
3673
|
PluginDevProxyModuleTopLevelAwait(),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@module-federation/vite",
|
|
3
|
-
"version": "1.14.
|
|
3
|
+
"version": "1.14.3",
|
|
4
4
|
"description": "Vite plugin for Module Federation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.cjs",
|
|
@@ -70,9 +70,9 @@
|
|
|
70
70
|
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
|
-
"@module-federation/dts-plugin": "2.3.
|
|
74
|
-
"@module-federation/runtime": "2.3.
|
|
75
|
-
"@module-federation/sdk": "2.3.
|
|
73
|
+
"@module-federation/dts-plugin": "2.3.2",
|
|
74
|
+
"@module-federation/runtime": "2.3.2",
|
|
75
|
+
"@module-federation/sdk": "2.3.2",
|
|
76
76
|
"@rollup/pluginutils": "^5.3.0",
|
|
77
77
|
"defu": "^6.1.4",
|
|
78
78
|
"es-module-lexer": "^2.0.0",
|