@module-federation/vite 1.13.5 → 1.13.7
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 +33 -13
- package/lib/index.cjs +418 -211
- package/lib/index.d.cts +3 -3
- package/lib/index.d.mts +4 -4
- package/lib/index.mjs +418 -211
- package/package.json +4 -4
package/lib/index.cjs
CHANGED
|
@@ -28,6 +28,7 @@ fs = __toESM(fs);
|
|
|
28
28
|
let module$1 = require("module");
|
|
29
29
|
let pathe = require("pathe");
|
|
30
30
|
pathe = __toESM(pathe);
|
|
31
|
+
let vite = require("vite");
|
|
31
32
|
let magic_string = require("magic-string");
|
|
32
33
|
magic_string = __toESM(magic_string);
|
|
33
34
|
let _rollup_pluginutils = require("@rollup/pluginutils");
|
|
@@ -152,11 +153,13 @@ function removePathFromNpmPackage(packageString) {
|
|
|
152
153
|
return match ? match[0] : packageString;
|
|
153
154
|
}
|
|
154
155
|
/**
|
|
155
|
-
* Detect whether the current runtime is Vite 8+
|
|
156
|
-
*
|
|
156
|
+
* Detect whether the current runtime is Vite 8+ by checking for a Vite version flag
|
|
157
|
+
* on the plugin hook context, with Rolldown metadata kept as a compatibility fallback.
|
|
157
158
|
*/
|
|
158
159
|
function getIsRolldown(ctx) {
|
|
159
|
-
|
|
160
|
+
const viteVersion = ctx?.meta?.viteVersion;
|
|
161
|
+
const viteMajor = Number(String(viteVersion ?? "").split(".")[0]);
|
|
162
|
+
return Number.isFinite(viteMajor) && viteMajor >= 8 || !!ctx?.meta?.rolldownVersion;
|
|
160
163
|
}
|
|
161
164
|
function hasPackageDependency(dependencyName, cwd = packageDetectionCwd || process.cwd()) {
|
|
162
165
|
const cacheKey = getDependencyCacheKey(cwd, dependencyName);
|
|
@@ -225,17 +228,21 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry" }) => {
|
|
|
225
228
|
next();
|
|
226
229
|
});
|
|
227
230
|
},
|
|
228
|
-
transformIndexHtml
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
231
|
+
transformIndexHtml: {
|
|
232
|
+
order: "pre",
|
|
233
|
+
handler(c) {
|
|
234
|
+
if (!injectHtml()) return;
|
|
235
|
+
clientInjected = true;
|
|
236
|
+
const base = viteConfig.base.replace(/\/$/, "");
|
|
237
|
+
const stripBase = (p) => base && p.startsWith(base) ? p.slice(base.length) : p;
|
|
238
|
+
const html = rewriteEntryScripts(c, (originalSrc) => {
|
|
239
|
+
return `/@id/${DEV_HTML_PROXY_PREFIX}${new URLSearchParams({
|
|
240
|
+
init: sanitizeDevEntryPath(stripBase(devEntryPath)),
|
|
241
|
+
entry: originalSrc
|
|
242
|
+
}).toString()}`;
|
|
243
|
+
});
|
|
244
|
+
return html === c ? injectEntryScript(c, stripBase(devEntryPath)) : html;
|
|
245
|
+
}
|
|
239
246
|
},
|
|
240
247
|
resolveId(id) {
|
|
241
248
|
if (id.startsWith(DEV_HTML_PROXY_PREFIX)) return id;
|
|
@@ -806,13 +813,13 @@ function normalizeLibrary(library) {
|
|
|
806
813
|
if (!library) return void 0;
|
|
807
814
|
return library;
|
|
808
815
|
}
|
|
809
|
-
function normalizeManifest(manifest
|
|
816
|
+
function normalizeManifest(manifest) {
|
|
817
|
+
if (manifest === void 0) return;
|
|
810
818
|
if (typeof manifest === "boolean") return manifest;
|
|
811
|
-
return
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
}, manifest);
|
|
819
|
+
return {
|
|
820
|
+
...manifest,
|
|
821
|
+
fileName: manifest.fileName || "mf-manifest.json"
|
|
822
|
+
};
|
|
816
823
|
}
|
|
817
824
|
let config;
|
|
818
825
|
function getNormalizeModuleFederationOptions() {
|
|
@@ -1231,6 +1238,13 @@ function escapeGeneratedStringLiteral(value) {
|
|
|
1231
1238
|
}
|
|
1232
1239
|
});
|
|
1233
1240
|
}
|
|
1241
|
+
function isValidJsIdentifier(name) {
|
|
1242
|
+
return /^[$_\p{ID_Start}][$_\u200C\u200D\p{ID_Continue}]*$/u.test(name);
|
|
1243
|
+
}
|
|
1244
|
+
function isValidEsmExportName(name) {
|
|
1245
|
+
return !!name && name !== "default" && name !== "__esModule" && isValidJsIdentifier(name);
|
|
1246
|
+
}
|
|
1247
|
+
const JS_IDENTIFIER_PATTERN = `[\$_\\p{ID_Start}][\$_\\u200C\\u200D\\p{ID_Continue}]*`;
|
|
1234
1248
|
const localRequire = (0, module$1.createRequire)(require("url").pathToFileURL(__filename).href);
|
|
1235
1249
|
function resolvePackageEntryFromProjectRoot(pkg) {
|
|
1236
1250
|
try {
|
|
@@ -1308,21 +1322,51 @@ function getPackageEsmEntryPath(pkg) {
|
|
|
1308
1322
|
}
|
|
1309
1323
|
}
|
|
1310
1324
|
function getEsmNamedExports(pkg) {
|
|
1325
|
+
let source = "";
|
|
1311
1326
|
try {
|
|
1312
1327
|
const entryPath = getPackageEsmEntryPath(pkg);
|
|
1313
1328
|
if (!entryPath) return [];
|
|
1314
1329
|
const { initSync, parse } = localRequire("es-module-lexer");
|
|
1315
1330
|
initSync();
|
|
1316
|
-
|
|
1317
|
-
|
|
1331
|
+
source = (0, fs.readFileSync)(entryPath, "utf-8");
|
|
1332
|
+
const [, exports] = parse(source, entryPath);
|
|
1333
|
+
const names = exports.map((item) => item.n).filter((name) => isValidEsmExportName(name));
|
|
1334
|
+
const regexNames = getNamedExportsViaRegex(source);
|
|
1335
|
+
const filteredNames = names.filter((name) => name !== "type" || regexNames.includes(name));
|
|
1336
|
+
if (filteredNames.length > 0) return [...new Set([...filteredNames, ...regexNames])];
|
|
1337
|
+
return regexNames;
|
|
1318
1338
|
} catch {
|
|
1319
|
-
return [];
|
|
1339
|
+
return source ? getNamedExportsViaRegex(source) : [];
|
|
1320
1340
|
}
|
|
1321
1341
|
}
|
|
1342
|
+
function getNamedExportsViaRegex(source) {
|
|
1343
|
+
const names = /* @__PURE__ */ new Set();
|
|
1344
|
+
const declRegex = new RegExp(`export\\s+(?:async\\s+)?(?:function(?:\\*\\s*|\\s+\\*?\\s*)|const\\s+|let\\s+|var\\s+|class\\s+)(${JS_IDENTIFIER_PATTERN})`, "gu");
|
|
1345
|
+
let match;
|
|
1346
|
+
while ((match = declRegex.exec(source)) !== null) {
|
|
1347
|
+
const name = match[1];
|
|
1348
|
+
if (isValidEsmExportName(name)) names.add(name);
|
|
1349
|
+
}
|
|
1350
|
+
const listRegex = /export\s*\{([^}]+)\}/g;
|
|
1351
|
+
const typeOnlySpecifierRegex = new RegExp(`^type\\s+${JS_IDENTIFIER_PATTERN}(?:\\s+as\\s+${JS_IDENTIFIER_PATTERN})?$`, "u");
|
|
1352
|
+
const exportSpecifierRegex = new RegExp(`(?:\\S+\\s+as\\s+)?(${JS_IDENTIFIER_PATTERN})$`, "u");
|
|
1353
|
+
while ((match = listRegex.exec(source)) !== null) {
|
|
1354
|
+
const specifiers = match[1].split(",");
|
|
1355
|
+
for (const specifier of specifiers) {
|
|
1356
|
+
const trimmed = specifier.trim();
|
|
1357
|
+
if (typeOnlySpecifierRegex.test(trimmed)) continue;
|
|
1358
|
+
const asMatch = trimmed.match(exportSpecifierRegex);
|
|
1359
|
+
if (!asMatch) continue;
|
|
1360
|
+
const name = asMatch[1];
|
|
1361
|
+
if (isValidEsmExportName(name)) names.add(name);
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
return [...names];
|
|
1365
|
+
}
|
|
1322
1366
|
function getPackageNamedExports(pkg) {
|
|
1323
1367
|
try {
|
|
1324
1368
|
const mod = (0, module$1.createRequire)(new URL(`file://${pathe.default.join(getPackageDetectionCwd(), "package.json")}`))(pkg);
|
|
1325
|
-
return Object.keys(mod).filter((k) =>
|
|
1369
|
+
return Object.keys(mod).filter((k) => isValidEsmExportName(k));
|
|
1326
1370
|
} catch {
|
|
1327
1371
|
return getEsmNamedExports(pkg);
|
|
1328
1372
|
}
|
|
@@ -1330,11 +1374,14 @@ function getPackageNamedExports(pkg) {
|
|
|
1330
1374
|
function getLocalProviderImportPath(pkg) {
|
|
1331
1375
|
try {
|
|
1332
1376
|
const resolved = (0, module$1.createRequire)(new URL(`file://${pathe.default.join(getPackageDetectionCwd(), "package.json")}`)).resolve(pkg);
|
|
1333
|
-
return resolved
|
|
1377
|
+
return isWorkspaceFilePath(resolved) ? resolved : void 0;
|
|
1334
1378
|
} catch {
|
|
1335
1379
|
return;
|
|
1336
1380
|
}
|
|
1337
1381
|
}
|
|
1382
|
+
function isWorkspaceFilePath(resolved) {
|
|
1383
|
+
return !!resolved && !resolved.includes("/node_modules/") && !resolved.includes("\\node_modules\\");
|
|
1384
|
+
}
|
|
1338
1385
|
function tryResolveImportFromPackageRoot(pkg, root) {
|
|
1339
1386
|
try {
|
|
1340
1387
|
return (0, module$1.createRequire)(new URL(`file://${pathe.default.join(root, "package.json")}`)).resolve(pkg);
|
|
@@ -1411,11 +1458,15 @@ function writeLoadShareModule(pkg, shareItem, command, isRolldown) {
|
|
|
1411
1458
|
`, true);
|
|
1412
1459
|
return;
|
|
1413
1460
|
}
|
|
1414
|
-
const
|
|
1461
|
+
const isVinext = hasPackageDependency("vinext");
|
|
1462
|
+
const isAstro = hasPackageDependency("astro");
|
|
1463
|
+
const useSsrProviderFallback = (isVinext || isAstro) && command === "build" && pkg === "react";
|
|
1415
1464
|
const concreteSharedImportSource = getConcreteSharedImportSource(pkg, shareItem);
|
|
1416
1465
|
const sharedImportSource = concreteSharedImportSource || getPreBuildLibImportId(pkg);
|
|
1417
1466
|
const devImportSource = concreteSharedImportSource || pkg;
|
|
1418
|
-
const
|
|
1467
|
+
const localProviderPath = getLocalProviderImportPath(pkg);
|
|
1468
|
+
const isWorkspacePackage = isWorkspaceFilePath(localProviderPath) || isWorkspaceFilePath(concreteSharedImportSource);
|
|
1469
|
+
const providerImportId = localProviderPath || concreteSharedImportSource || sharedImportSource;
|
|
1419
1470
|
const namedExports = getPackageNamedExports(pkg);
|
|
1420
1471
|
let exportLine;
|
|
1421
1472
|
if (namedExports.length > 0) {
|
|
@@ -1423,9 +1474,11 @@ function writeLoadShareModule(pkg, shareItem, command, isRolldown) {
|
|
|
1423
1474
|
const namedExportLine = `export { ${namedExports.map((name, i) => `__mf_${i} as ${name}`).join(", ")} };`;
|
|
1424
1475
|
exportLine = useESM ? `export default exportModule.default ?? exportModule;\n ${destructure}\n ${namedExportLine}` : `module.exports = exportModule;\n ${destructure}\n Object.assign(module.exports, { ${namedExports.map((name, i) => `"${name}": __mf_${i}`).join(", ")} });`;
|
|
1425
1476
|
} else exportLine = useESM ? `export default exportModule.default ?? exportModule\n export * from ${escapeGeneratedStringLiteral(sharedImportSource)}` : "module.exports = exportModule";
|
|
1477
|
+
const prebuildImportLine = isWorkspacePackage && command !== "build" ? "" : `import ${escapeGeneratedStringLiteral(sharedImportSource)};`;
|
|
1478
|
+
const devDynamicImportLine = isWorkspacePackage ? "" : command !== "build" ? `;() => import(${escapeGeneratedStringLiteral(devImportSource)}).catch(() => {});` : "";
|
|
1426
1479
|
loadShareCacheMap[pkg].writeSync(`
|
|
1427
|
-
|
|
1428
|
-
${
|
|
1480
|
+
${prebuildImportLine}
|
|
1481
|
+
${devDynamicImportLine}
|
|
1429
1482
|
${importLine}
|
|
1430
1483
|
${useSsrProviderFallback ? `const providerModulePromise = typeof window === "undefined"
|
|
1431
1484
|
? import(${escapeGeneratedStringLiteral(providerImportId)})
|
|
@@ -1466,6 +1519,8 @@ function writeLocalSharedImportMap() {
|
|
|
1466
1519
|
}
|
|
1467
1520
|
function generateLocalSharedImportMap() {
|
|
1468
1521
|
const isVinext = hasPackageDependency("vinext");
|
|
1522
|
+
const isAstro = hasPackageDependency("astro");
|
|
1523
|
+
const useDirectReactImport = isVinext || isAstro;
|
|
1469
1524
|
const options = getNormalizeModuleFederationOptions();
|
|
1470
1525
|
return `
|
|
1471
1526
|
import {loadShare} from "@module-federation/runtime";
|
|
@@ -1474,7 +1529,7 @@ function generateLocalSharedImportMap() {
|
|
|
1474
1529
|
const shareItem = getNormalizeShareItem(pkg);
|
|
1475
1530
|
return `
|
|
1476
1531
|
${JSON.stringify(pkg)}: async () => {
|
|
1477
|
-
${shareItem?.shareConfig.import === false ? `throw new Error(\`[Module Federation] Shared module '\${${JSON.stringify(pkg)}}' must be provided by host\`);` :
|
|
1532
|
+
${shareItem?.shareConfig.import === false ? `throw new Error(\`[Module Federation] Shared module '\${${JSON.stringify(pkg)}}' must be provided by host\`);` : useDirectReactImport && pkg === "react" ? `let pkg = await import("react");
|
|
1478
1533
|
return pkg;` : `let pkg = await import(${JSON.stringify(getSharedImportSource(pkg, shareItem))});
|
|
1479
1534
|
return pkg;`}
|
|
1480
1535
|
}
|
|
@@ -1499,7 +1554,7 @@ function generateLocalSharedImportMap() {
|
|
|
1499
1554
|
usedShared[${JSON.stringify(key)}].loaded = true
|
|
1500
1555
|
const {${JSON.stringify(key)}: pkgDynamicImport} = importMap
|
|
1501
1556
|
const res = await pkgDynamicImport()
|
|
1502
|
-
const exportModule = ${JSON.stringify(
|
|
1557
|
+
const exportModule = ${JSON.stringify(useDirectReactImport)} && ${JSON.stringify(key)} === "react"
|
|
1503
1558
|
? (res?.default ?? res)
|
|
1504
1559
|
: {...res}
|
|
1505
1560
|
// All npm packages pre-built by vite will be converted to esm
|
|
@@ -1814,7 +1869,7 @@ const buildFileToShareKeyMap = async (shareKeys, resolveFn) => {
|
|
|
1814
1869
|
* @returns The resolved public path
|
|
1815
1870
|
*/
|
|
1816
1871
|
function resolvePublicPath(options, viteBase, originalBase) {
|
|
1817
|
-
if (options.publicPath) return options.publicPath;
|
|
1872
|
+
if (options.publicPath && options.publicPath !== "auto") return options.publicPath;
|
|
1818
1873
|
if (originalBase === "") return "auto";
|
|
1819
1874
|
if (viteBase) return viteBase.replace(/\/?$/, "/");
|
|
1820
1875
|
return "auto";
|
|
@@ -1824,9 +1879,17 @@ function resolvePublicPath(options, viteBase, originalBase) {
|
|
|
1824
1879
|
const Manifest = () => {
|
|
1825
1880
|
const mfOptions = getNormalizeModuleFederationOptions();
|
|
1826
1881
|
const { name, filename, getPublicPath, manifest: manifestOptions, varFilename } = mfOptions;
|
|
1827
|
-
let mfManifestName = "";
|
|
1828
|
-
|
|
1829
|
-
|
|
1882
|
+
let mfManifestName = manifestOptions === true ? "mf-manifest.json" : typeof manifestOptions === "object" ? pathe.join(manifestOptions?.filePath || "", manifestOptions?.fileName || "mf-manifest.json") : void 0;
|
|
1883
|
+
let mfManifestStatsName = mfManifestName ? getStatsFileName(mfManifestName) : void 0;
|
|
1884
|
+
const isConsumerProject = Object.keys(mfOptions.exposes).length === 0;
|
|
1885
|
+
let disableAssetsAnalyze = false;
|
|
1886
|
+
const getDefaultDisableAssetsAnalyze = (command) => command === "serve" && isConsumerProject && (typeof manifestOptions !== "object" || !Object.prototype.hasOwnProperty.call(manifestOptions, "disableAssetsAnalyze"));
|
|
1887
|
+
const getConfiguredDisableAssetsAnalyze = (command) => {
|
|
1888
|
+
if (typeof manifestOptions === "object" && manifestOptions !== null) {
|
|
1889
|
+
if (Object.prototype.hasOwnProperty.call(manifestOptions, "disableAssetsAnalyze")) return manifestOptions.disableAssetsAnalyze === true;
|
|
1890
|
+
}
|
|
1891
|
+
return getDefaultDisableAssetsAnalyze(command);
|
|
1892
|
+
};
|
|
1830
1893
|
let root;
|
|
1831
1894
|
let remoteEntryFile;
|
|
1832
1895
|
let publicPath;
|
|
@@ -1861,7 +1924,7 @@ const Manifest = () => {
|
|
|
1861
1924
|
res.setHeader("Content-Type", "application/json");
|
|
1862
1925
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
1863
1926
|
res.end(JSON.stringify({
|
|
1864
|
-
...generateMFManifest({}),
|
|
1927
|
+
...generateMFManifest({}, disableAssetsAnalyze),
|
|
1865
1928
|
id: name,
|
|
1866
1929
|
name,
|
|
1867
1930
|
metaData: {
|
|
@@ -1902,9 +1965,10 @@ const Manifest = () => {
|
|
|
1902
1965
|
name: "module-federation-manifest",
|
|
1903
1966
|
enforce: "post",
|
|
1904
1967
|
config(config, { command }) {
|
|
1905
|
-
if (!config.build) config.build = {};
|
|
1906
|
-
if (!config.build.manifest) config.build.manifest = config.build.manifest || !!manifestOptions;
|
|
1907
1968
|
_command = command;
|
|
1969
|
+
if (!config.build) config.build = {};
|
|
1970
|
+
if (!config.build.manifest) config.build.manifest = config.build.manifest || !!mfManifestName;
|
|
1971
|
+
disableAssetsAnalyze = getConfiguredDisableAssetsAnalyze(command);
|
|
1908
1972
|
_originalConfigBase = config.base;
|
|
1909
1973
|
},
|
|
1910
1974
|
configResolved(config) {
|
|
@@ -1918,28 +1982,35 @@ const Manifest = () => {
|
|
|
1918
1982
|
let filesMap = {};
|
|
1919
1983
|
const foundRemoteEntryFile = findRemoteEntryFile(mfOptions.filename, bundle);
|
|
1920
1984
|
if (foundRemoteEntryFile) remoteEntryFile = foundRemoteEntryFile;
|
|
1921
|
-
const allCssAssets = mfOptions.bundleAllCSS ? collectCssAssets(bundle) : /* @__PURE__ */ new Set();
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
const
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1985
|
+
const allCssAssets = mfOptions.bundleAllCSS && !disableAssetsAnalyze ? collectCssAssets(bundle) : /* @__PURE__ */ new Set();
|
|
1986
|
+
if (!disableAssetsAnalyze) {
|
|
1987
|
+
const exposesModules = Object.keys(mfOptions.exposes).map((item) => mfOptions.exposes[item].import);
|
|
1988
|
+
processModuleAssets(bundle, filesMap, (modulePath) => {
|
|
1989
|
+
const absoluteModulePath = pathe.resolve(root, modulePath);
|
|
1990
|
+
return exposesModules.find((exposeModule) => {
|
|
1991
|
+
const exposePath = pathe.resolve(root, exposeModule);
|
|
1992
|
+
if (absoluteModulePath === exposePath) return true;
|
|
1993
|
+
const getPathWithoutKnownExt = (filePath) => {
|
|
1994
|
+
const ext = pathe.extname(filePath);
|
|
1995
|
+
return JS_EXTENSIONS.includes(ext) ? pathe.join(pathe.dirname(filePath), pathe.basename(filePath, ext)) : filePath;
|
|
1996
|
+
};
|
|
1997
|
+
return getPathWithoutKnownExt(absoluteModulePath) === getPathWithoutKnownExt(exposePath);
|
|
1998
|
+
});
|
|
1933
1999
|
});
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
2000
|
+
const fileToShareKey = await buildFileToShareKeyMap(getUsedShares(), this.resolve.bind(this));
|
|
2001
|
+
processModuleAssets(bundle, filesMap, (modulePath) => fileToShareKey.get(modulePath));
|
|
2002
|
+
if (mfOptions.bundleAllCSS) addCssAssetsToAllExports(filesMap, allCssAssets);
|
|
2003
|
+
filesMap = deduplicateAssets(filesMap);
|
|
2004
|
+
}
|
|
1939
2005
|
this.emitFile({
|
|
1940
2006
|
type: "asset",
|
|
1941
2007
|
fileName: mfManifestName,
|
|
1942
|
-
source: JSON.stringify(generateMFManifest(filesMap))
|
|
2008
|
+
source: JSON.stringify(generateMFManifest(filesMap, disableAssetsAnalyze))
|
|
2009
|
+
});
|
|
2010
|
+
if (mfManifestStatsName) this.emitFile({
|
|
2011
|
+
type: "asset",
|
|
2012
|
+
fileName: mfManifestStatsName,
|
|
2013
|
+
source: JSON.stringify(generateMFStats(filesMap, bundle, disableAssetsAnalyze))
|
|
1943
2014
|
});
|
|
1944
2015
|
}
|
|
1945
2016
|
}];
|
|
@@ -1948,7 +2019,7 @@ const Manifest = () => {
|
|
|
1948
2019
|
* @param preloadMap - Map of module assets to include
|
|
1949
2020
|
* @returns Complete manifest object
|
|
1950
2021
|
*/
|
|
1951
|
-
function generateMFManifest(preloadMap) {
|
|
2022
|
+
function generateMFManifest(preloadMap, disableAssetsAnalyze = false) {
|
|
1952
2023
|
const options = getNormalizeModuleFederationOptions();
|
|
1953
2024
|
const { name, varFilename } = options;
|
|
1954
2025
|
const remoteEntry = {
|
|
@@ -1974,6 +2045,7 @@ const Manifest = () => {
|
|
|
1974
2045
|
id: `${name}:${shareKey}`,
|
|
1975
2046
|
name: shareKey,
|
|
1976
2047
|
version: shareItem.version,
|
|
2048
|
+
singleton: shareItem.shareConfig.singleton,
|
|
1977
2049
|
requiredVersion: shareItem.shareConfig.requiredVersion,
|
|
1978
2050
|
assets: {
|
|
1979
2051
|
js: {
|
|
@@ -2027,12 +2099,33 @@ const Manifest = () => {
|
|
|
2027
2099
|
pluginVersion: "0.2.5",
|
|
2028
2100
|
...!!getPublicPath ? { getPublicPath } : { publicPath }
|
|
2029
2101
|
},
|
|
2030
|
-
shared,
|
|
2102
|
+
...disableAssetsAnalyze ? {} : { shared },
|
|
2031
2103
|
remotes,
|
|
2032
|
-
exposes
|
|
2104
|
+
...disableAssetsAnalyze ? {} : { exposes }
|
|
2105
|
+
};
|
|
2106
|
+
}
|
|
2107
|
+
function generateMFStats(preloadMap, bundle, disableAssetsAnalyze = false) {
|
|
2108
|
+
const baseManifest = generateMFManifest(preloadMap, disableAssetsAnalyze);
|
|
2109
|
+
const bundleSummary = Object.entries(bundle).map(([fileName, chunkOrAsset]) => ({
|
|
2110
|
+
fileName,
|
|
2111
|
+
type: chunkOrAsset.type,
|
|
2112
|
+
isEntry: chunkOrAsset.isEntry || false,
|
|
2113
|
+
size: typeof chunkOrAsset.code === "string" ? chunkOrAsset.code.length : chunkOrAsset.source?.length || chunkOrAsset.source?.byteLength || void 0
|
|
2114
|
+
}));
|
|
2115
|
+
return {
|
|
2116
|
+
...baseManifest,
|
|
2117
|
+
buildOutput: bundleSummary,
|
|
2118
|
+
...disableAssetsAnalyze ? {} : { assetAnalysis: preloadMap }
|
|
2033
2119
|
};
|
|
2034
2120
|
}
|
|
2035
2121
|
};
|
|
2122
|
+
function getStatsFileName(manifestFileName) {
|
|
2123
|
+
const parsed = pathe.parse(manifestFileName);
|
|
2124
|
+
const fileExt = parsed.ext || ".json";
|
|
2125
|
+
const baseName = parsed.ext ? parsed.name : parsed.base;
|
|
2126
|
+
const fileName = `${baseName === "mf-manifest" ? "mf" : baseName}-stats${fileExt}`;
|
|
2127
|
+
return parsed.dir ? pathe.join(parsed.dir, fileName) : fileName;
|
|
2128
|
+
}
|
|
2036
2129
|
//#endregion
|
|
2037
2130
|
//#region src/plugins/pluginModuleParseEnd.ts
|
|
2038
2131
|
let _resolve, _parseTimeout;
|
|
@@ -2236,6 +2329,130 @@ function pluginProxyRemotes_default(options) {
|
|
|
2236
2329
|
};
|
|
2237
2330
|
}
|
|
2238
2331
|
//#endregion
|
|
2332
|
+
//#region src/utils/PromiseStore.ts
|
|
2333
|
+
/**
|
|
2334
|
+
* example:
|
|
2335
|
+
* const store = new PromiseStore<number>();
|
|
2336
|
+
* store.get("example").then((result) => {
|
|
2337
|
+
* console.log("Result from example:", result); // 42
|
|
2338
|
+
* });
|
|
2339
|
+
* setTimeout(() => {
|
|
2340
|
+
* store.set("example", Promise.resolve(42));
|
|
2341
|
+
* }, 2000);
|
|
2342
|
+
*/
|
|
2343
|
+
var PromiseStore = class {
|
|
2344
|
+
constructor() {
|
|
2345
|
+
this.promiseMap = /* @__PURE__ */ new Map();
|
|
2346
|
+
this.resolveMap = /* @__PURE__ */ new Map();
|
|
2347
|
+
}
|
|
2348
|
+
set(id, promise) {
|
|
2349
|
+
if (this.resolveMap.has(id)) {
|
|
2350
|
+
promise.then(this.resolveMap.get(id));
|
|
2351
|
+
this.resolveMap.delete(id);
|
|
2352
|
+
}
|
|
2353
|
+
this.promiseMap.set(id, promise);
|
|
2354
|
+
}
|
|
2355
|
+
get(id) {
|
|
2356
|
+
if (this.promiseMap.has(id)) return this.promiseMap.get(id);
|
|
2357
|
+
const pendingPromise = new Promise((resolve) => {
|
|
2358
|
+
this.resolveMap.set(id, resolve);
|
|
2359
|
+
});
|
|
2360
|
+
this.promiseMap.set(id, pendingPromise);
|
|
2361
|
+
return pendingPromise;
|
|
2362
|
+
}
|
|
2363
|
+
};
|
|
2364
|
+
//#endregion
|
|
2365
|
+
//#region src/plugins/pluginProxySharedModule_preBuild.ts
|
|
2366
|
+
function getPrebuildResolutionSource(pkgName, shareItem) {
|
|
2367
|
+
return getConcreteSharedImportSource(pkgName, shareItem) || pkgName;
|
|
2368
|
+
}
|
|
2369
|
+
function proxySharedModule(options) {
|
|
2370
|
+
const { shared = {} } = options;
|
|
2371
|
+
let _config;
|
|
2372
|
+
let _command = "serve";
|
|
2373
|
+
let useDirectReactImport = false;
|
|
2374
|
+
const savePrebuild = new PromiseStore();
|
|
2375
|
+
return [{
|
|
2376
|
+
name: "generateLocalSharedImportMap",
|
|
2377
|
+
enforce: "post",
|
|
2378
|
+
load(id) {
|
|
2379
|
+
if (id.includes(getLocalSharedImportMapPath())) return parsePromise.then((_) => generateLocalSharedImportMap());
|
|
2380
|
+
},
|
|
2381
|
+
transform(_, id) {
|
|
2382
|
+
if (id.includes(getLocalSharedImportMapPath())) return mapCodeToCodeWithSourcemap(parsePromise.then((_) => generateLocalSharedImportMap()));
|
|
2383
|
+
}
|
|
2384
|
+
}, {
|
|
2385
|
+
name: "proxyPreBuildShared",
|
|
2386
|
+
enforce: "post",
|
|
2387
|
+
config(config, { command }) {
|
|
2388
|
+
setPackageDetectionCwd(config.root || process.cwd());
|
|
2389
|
+
const isVinext = hasPackageDependency("vinext");
|
|
2390
|
+
const isAstro = hasPackageDependency("astro");
|
|
2391
|
+
const isRolldown = getIsRolldown(this);
|
|
2392
|
+
_command = command;
|
|
2393
|
+
useDirectReactImport = isVinext || isAstro;
|
|
2394
|
+
config.resolve.alias.push(...Object.keys(shared).filter((key) => !(useDirectReactImport && key === "react")).map((key) => {
|
|
2395
|
+
const keyBase = key.endsWith("/") ? key.slice(0, -1) : key;
|
|
2396
|
+
const escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2397
|
+
const escapedKeyBase = escapeRegex(keyBase);
|
|
2398
|
+
const pattern = key.endsWith("/") ? `^(${escapedKeyBase}(?:\\/.*)?)$` : `^(${escapedKeyBase})$`;
|
|
2399
|
+
return {
|
|
2400
|
+
find: new RegExp(pattern),
|
|
2401
|
+
replacement: "$1",
|
|
2402
|
+
customResolver(source, importer) {
|
|
2403
|
+
if (/\.css$/.test(source)) return;
|
|
2404
|
+
if (useDirectReactImport && source === "react") return;
|
|
2405
|
+
if (importer && importer.includes("localSharedImportMap")) return;
|
|
2406
|
+
if (key.endsWith("/") && source !== key.slice(0, -1)) return;
|
|
2407
|
+
const loadSharePath = getLoadShareModulePath(source, isRolldown, command);
|
|
2408
|
+
writeLoadShareModule(source, shared[key], command, isRolldown);
|
|
2409
|
+
if (shared[key].shareConfig.import !== false) writePreBuildLibPath(source, shared[key]);
|
|
2410
|
+
addUsedShares(source);
|
|
2411
|
+
writeLocalSharedImportMap();
|
|
2412
|
+
return this.resolve(loadSharePath, importer);
|
|
2413
|
+
}
|
|
2414
|
+
};
|
|
2415
|
+
}));
|
|
2416
|
+
config.resolve.alias.push(...Object.keys(shared).filter((key) => !(useDirectReactImport && key === "react")).map((key) => {
|
|
2417
|
+
return command === "build" ? {
|
|
2418
|
+
find: new RegExp(`(.*${PREBUILD_TAG}.*)`),
|
|
2419
|
+
replacement: function($1) {
|
|
2420
|
+
const pkgName = assertModuleFound(PREBUILD_TAG, $1).name;
|
|
2421
|
+
return getPrebuildResolutionSource(pkgName, getPreBuildShareItem(pkgName));
|
|
2422
|
+
}
|
|
2423
|
+
} : {
|
|
2424
|
+
find: new RegExp(`(.*${PREBUILD_TAG}.*)`),
|
|
2425
|
+
replacement: "$1",
|
|
2426
|
+
async customResolver(source, importer) {
|
|
2427
|
+
const pkgName = assertModuleFound(PREBUILD_TAG, source).name;
|
|
2428
|
+
const importSource = getPrebuildResolutionSource(pkgName, getPreBuildShareItem(pkgName));
|
|
2429
|
+
const resolved = await this.resolve(importSource, importer);
|
|
2430
|
+
if (!resolved?.id) return;
|
|
2431
|
+
const result = resolved.id;
|
|
2432
|
+
if (_config && !result.includes(_config.cacheDir)) savePrebuild.set(pkgName, Promise.resolve(result));
|
|
2433
|
+
return await this.resolve(await savePrebuild.get(pkgName), importer);
|
|
2434
|
+
}
|
|
2435
|
+
};
|
|
2436
|
+
}));
|
|
2437
|
+
},
|
|
2438
|
+
configResolved(config) {
|
|
2439
|
+
_config = config;
|
|
2440
|
+
const isRolldown = getIsRolldown(this);
|
|
2441
|
+
Object.keys(shared).forEach((key) => {
|
|
2442
|
+
if (key.endsWith("/")) return;
|
|
2443
|
+
if (useDirectReactImport && key === "react") {
|
|
2444
|
+
addUsedShares(key);
|
|
2445
|
+
return;
|
|
2446
|
+
}
|
|
2447
|
+
writeLoadShareModule(key, shared[key], _command, isRolldown);
|
|
2448
|
+
if (shared[key].shareConfig.import !== false) writePreBuildLibPath(key, shared[key]);
|
|
2449
|
+
addUsedShares(key);
|
|
2450
|
+
});
|
|
2451
|
+
writeLocalSharedImportMap();
|
|
2452
|
+
}
|
|
2453
|
+
}];
|
|
2454
|
+
}
|
|
2455
|
+
//#endregion
|
|
2239
2456
|
//#region src/plugins/pluginRemoteNamedExports.ts
|
|
2240
2457
|
/**
|
|
2241
2458
|
* Transforms consumer-side imports of remote modules so that named exports
|
|
@@ -2258,6 +2475,7 @@ function pluginProxyRemotes_default(options) {
|
|
|
2258
2475
|
* build time. Use explicit named re-exports instead.
|
|
2259
2476
|
*/
|
|
2260
2477
|
const JS_EXTENSIONS_RE = /\.(?:[mc]?[jt]sx?|vue|svelte)(?:\?|$)/;
|
|
2478
|
+
const REGEX_FALLBACK_EXTENSIONS_RE = /\.(?:[mc]?[jt]sx?)(?:\?|$)/;
|
|
2261
2479
|
function wrapDynamicImport(original) {
|
|
2262
2480
|
return `${original}.then(function(__mf_m__) {\n if (!__mf_m__ || !__mf_m__.__moduleExports) return __mf_m__;\n var __mf_ns__ = Object.create(null);\n Object.defineProperty(__mf_ns__, Symbol.toStringTag, { value: "Module" });\n var __mf_e__ = __mf_m__.__moduleExports;\n Object.keys(__mf_e__).forEach(function(k) { if (k !== "__esModule") __mf_ns__[k] = __mf_e__[k] });\n if ("default" in __mf_m__) __mf_ns__.default = __mf_m__.default;\n return __mf_ns__;\n})`;
|
|
2263
2481
|
}
|
|
@@ -2467,18 +2685,96 @@ async function collectFromEsLexer(code, isRemoteImport) {
|
|
|
2467
2685
|
}
|
|
2468
2686
|
return result;
|
|
2469
2687
|
}
|
|
2688
|
+
function collectFromRegex(code, isRemoteImport) {
|
|
2689
|
+
const result = [];
|
|
2690
|
+
for (const match of code.matchAll(/^\s*import\s+([\s\S]*?)\s+from\s+(['"])([^'"]+)\2\s*;?/gm)) {
|
|
2691
|
+
const [full, specifiersPartRaw, , source] = match;
|
|
2692
|
+
if (!isRemoteImport(source)) continue;
|
|
2693
|
+
const specifiersPart = specifiersPartRaw.trim();
|
|
2694
|
+
if (/^type\s/.test(specifiersPart)) continue;
|
|
2695
|
+
const nsMatch = specifiersPart.match(/^\*\s+as\s+(\w+)$/);
|
|
2696
|
+
if (nsMatch) {
|
|
2697
|
+
result.push({
|
|
2698
|
+
kind: "static",
|
|
2699
|
+
source,
|
|
2700
|
+
start: match.index,
|
|
2701
|
+
end: match.index + full.length,
|
|
2702
|
+
named: [],
|
|
2703
|
+
namespaceLocal: nsMatch[1]
|
|
2704
|
+
});
|
|
2705
|
+
continue;
|
|
2706
|
+
}
|
|
2707
|
+
const braceMatch = specifiersPart.match(/\{([^}]*)\}/);
|
|
2708
|
+
if (!braceMatch) continue;
|
|
2709
|
+
const namedSpecifiers = braceMatch[1].split(",").map((s) => s.trim()).filter((s) => s.length > 0 && !s.startsWith("type "));
|
|
2710
|
+
if (namedSpecifiers.length === 0) continue;
|
|
2711
|
+
const defaultMatch = specifiersPart.match(/^(\w+)\s*,/);
|
|
2712
|
+
const named = namedSpecifiers.map((s) => {
|
|
2713
|
+
const asMatch = s.match(/^(\w+)\s+as\s+(\w+)$/);
|
|
2714
|
+
return {
|
|
2715
|
+
imported: asMatch ? asMatch[1] : s,
|
|
2716
|
+
local: asMatch ? asMatch[2] : s
|
|
2717
|
+
};
|
|
2718
|
+
});
|
|
2719
|
+
result.push({
|
|
2720
|
+
kind: "static",
|
|
2721
|
+
source,
|
|
2722
|
+
start: match.index,
|
|
2723
|
+
end: match.index + full.length,
|
|
2724
|
+
named,
|
|
2725
|
+
defaultLocal: defaultMatch?.[1]
|
|
2726
|
+
});
|
|
2727
|
+
}
|
|
2728
|
+
for (const match of code.matchAll(/^\s*export\s+\{([\s\S]*?)\}\s+from\s+(['"])([^'"]+)\2\s*;?/gm)) {
|
|
2729
|
+
const [full, specifiersRaw, , source] = match;
|
|
2730
|
+
if (!isRemoteImport(source)) continue;
|
|
2731
|
+
const specs = specifiersRaw.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
2732
|
+
if (specs.length === 0) continue;
|
|
2733
|
+
result.push({
|
|
2734
|
+
kind: "reexport",
|
|
2735
|
+
source,
|
|
2736
|
+
start: match.index,
|
|
2737
|
+
end: match.index + full.length,
|
|
2738
|
+
specifiers: specs.map((s) => {
|
|
2739
|
+
const asMatch = s.match(/^(\w+)\s+as\s+(\w+)$/);
|
|
2740
|
+
return {
|
|
2741
|
+
local: asMatch ? asMatch[1] : s,
|
|
2742
|
+
exported: asMatch ? asMatch[2] : s
|
|
2743
|
+
};
|
|
2744
|
+
})
|
|
2745
|
+
});
|
|
2746
|
+
}
|
|
2747
|
+
for (const match of code.matchAll(/^\s*export\s+\*\s+from\s+(['"])([^'"]+)\1\s*;?/gm)) {
|
|
2748
|
+
const [full, , source] = match;
|
|
2749
|
+
if (!isRemoteImport(source)) continue;
|
|
2750
|
+
result.push({
|
|
2751
|
+
kind: "export-all",
|
|
2752
|
+
source,
|
|
2753
|
+
start: match.index,
|
|
2754
|
+
end: match.index + full.length
|
|
2755
|
+
});
|
|
2756
|
+
}
|
|
2757
|
+
for (const match of code.matchAll(/import\(\s*(['"])([^'"]+)\1\s*\)/g)) {
|
|
2758
|
+
const [full, , source] = match;
|
|
2759
|
+
if (!isRemoteImport(source)) continue;
|
|
2760
|
+
result.push({
|
|
2761
|
+
kind: "dynamic",
|
|
2762
|
+
start: match.index,
|
|
2763
|
+
end: match.index + full.length,
|
|
2764
|
+
originalText: full
|
|
2765
|
+
});
|
|
2766
|
+
}
|
|
2767
|
+
return result.length > 0 ? result : void 0;
|
|
2768
|
+
}
|
|
2470
2769
|
function pluginRemoteNamedExports(options) {
|
|
2471
2770
|
const remoteNames = Object.keys(options.remotes);
|
|
2472
|
-
let rolldown;
|
|
2473
2771
|
function isRemoteImport(source) {
|
|
2474
|
-
return remoteNames.some((name) => source === name || source.startsWith(name + "/"));
|
|
2772
|
+
return remoteNames.some((name) => source === name || source.startsWith(name + "/")) || source.includes("__loadRemote__");
|
|
2475
2773
|
}
|
|
2476
2774
|
return {
|
|
2477
2775
|
name: "module-federation-remote-named-exports",
|
|
2478
|
-
enforce: "
|
|
2776
|
+
enforce: "post",
|
|
2479
2777
|
async transform(code, id) {
|
|
2480
|
-
rolldown ??= getIsRolldown(this);
|
|
2481
|
-
if (!rolldown) return;
|
|
2482
2778
|
if (remoteNames.length === 0) return;
|
|
2483
2779
|
if (id.includes("__loadRemote__") || id.includes("__loadShare__")) return;
|
|
2484
2780
|
if (!JS_EXTENSIONS_RE.test(id)) return;
|
|
@@ -2489,134 +2785,13 @@ function pluginRemoteNamedExports(options) {
|
|
|
2489
2785
|
} catch {
|
|
2490
2786
|
imports = await collectFromEsLexer(code, isRemoteImport);
|
|
2491
2787
|
}
|
|
2788
|
+
if ((!imports || imports.length === 0) && REGEX_FALLBACK_EXTENSIONS_RE.test(id)) imports = collectFromRegex(code, isRemoteImport);
|
|
2492
2789
|
if (!imports) return;
|
|
2493
2790
|
return applyRewrites(code, imports, id);
|
|
2494
2791
|
}
|
|
2495
2792
|
};
|
|
2496
2793
|
}
|
|
2497
2794
|
//#endregion
|
|
2498
|
-
//#region src/utils/PromiseStore.ts
|
|
2499
|
-
/**
|
|
2500
|
-
* example:
|
|
2501
|
-
* const store = new PromiseStore<number>();
|
|
2502
|
-
* store.get("example").then((result) => {
|
|
2503
|
-
* console.log("Result from example:", result); // 42
|
|
2504
|
-
* });
|
|
2505
|
-
* setTimeout(() => {
|
|
2506
|
-
* store.set("example", Promise.resolve(42));
|
|
2507
|
-
* }, 2000);
|
|
2508
|
-
*/
|
|
2509
|
-
var PromiseStore = class {
|
|
2510
|
-
constructor() {
|
|
2511
|
-
this.promiseMap = /* @__PURE__ */ new Map();
|
|
2512
|
-
this.resolveMap = /* @__PURE__ */ new Map();
|
|
2513
|
-
}
|
|
2514
|
-
set(id, promise) {
|
|
2515
|
-
if (this.resolveMap.has(id)) {
|
|
2516
|
-
promise.then(this.resolveMap.get(id));
|
|
2517
|
-
this.resolveMap.delete(id);
|
|
2518
|
-
}
|
|
2519
|
-
this.promiseMap.set(id, promise);
|
|
2520
|
-
}
|
|
2521
|
-
get(id) {
|
|
2522
|
-
if (this.promiseMap.has(id)) return this.promiseMap.get(id);
|
|
2523
|
-
const pendingPromise = new Promise((resolve) => {
|
|
2524
|
-
this.resolveMap.set(id, resolve);
|
|
2525
|
-
});
|
|
2526
|
-
this.promiseMap.set(id, pendingPromise);
|
|
2527
|
-
return pendingPromise;
|
|
2528
|
-
}
|
|
2529
|
-
};
|
|
2530
|
-
//#endregion
|
|
2531
|
-
//#region src/plugins/pluginProxySharedModule_preBuild.ts
|
|
2532
|
-
function getPrebuildResolutionSource(pkgName, shareItem) {
|
|
2533
|
-
return getConcreteSharedImportSource(pkgName, shareItem) || pkgName;
|
|
2534
|
-
}
|
|
2535
|
-
function proxySharedModule(options) {
|
|
2536
|
-
const { shared = {} } = options;
|
|
2537
|
-
let _config;
|
|
2538
|
-
let _command = "serve";
|
|
2539
|
-
let isVinext = false;
|
|
2540
|
-
const savePrebuild = new PromiseStore();
|
|
2541
|
-
return [{
|
|
2542
|
-
name: "generateLocalSharedImportMap",
|
|
2543
|
-
enforce: "post",
|
|
2544
|
-
load(id) {
|
|
2545
|
-
if (id.includes(getLocalSharedImportMapPath())) return parsePromise.then((_) => generateLocalSharedImportMap());
|
|
2546
|
-
},
|
|
2547
|
-
transform(_, id) {
|
|
2548
|
-
if (id.includes(getLocalSharedImportMapPath())) return mapCodeToCodeWithSourcemap(parsePromise.then((_) => generateLocalSharedImportMap()));
|
|
2549
|
-
}
|
|
2550
|
-
}, {
|
|
2551
|
-
name: "proxyPreBuildShared",
|
|
2552
|
-
enforce: "post",
|
|
2553
|
-
config(config, { command }) {
|
|
2554
|
-
setPackageDetectionCwd(config.root || process.cwd());
|
|
2555
|
-
isVinext = hasPackageDependency("vinext");
|
|
2556
|
-
const isRolldown = getIsRolldown(this);
|
|
2557
|
-
_command = command;
|
|
2558
|
-
config.resolve.alias.push(...Object.keys(shared).filter((key) => !(isVinext && key === "react")).map((key) => {
|
|
2559
|
-
const keyBase = key.endsWith("/") ? key.slice(0, -1) : key;
|
|
2560
|
-
const escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2561
|
-
const escapedKeyBase = escapeRegex(keyBase);
|
|
2562
|
-
const pattern = key.endsWith("/") ? `^(${escapedKeyBase}(?:\\/.*)?)$` : `^(${escapedKeyBase})$`;
|
|
2563
|
-
return {
|
|
2564
|
-
find: new RegExp(pattern),
|
|
2565
|
-
replacement: "$1",
|
|
2566
|
-
customResolver(source, importer) {
|
|
2567
|
-
if (/\.css$/.test(source)) return;
|
|
2568
|
-
if (isVinext && source === "react") return;
|
|
2569
|
-
if (importer && importer.includes("localSharedImportMap")) return;
|
|
2570
|
-
if (key.endsWith("/") && source !== key.slice(0, -1)) return;
|
|
2571
|
-
const loadSharePath = getLoadShareModulePath(source, isRolldown, command);
|
|
2572
|
-
writeLoadShareModule(source, shared[key], command, isRolldown);
|
|
2573
|
-
if (shared[key].shareConfig.import !== false) writePreBuildLibPath(source, shared[key]);
|
|
2574
|
-
addUsedShares(source);
|
|
2575
|
-
writeLocalSharedImportMap();
|
|
2576
|
-
return this.resolve(loadSharePath, importer);
|
|
2577
|
-
}
|
|
2578
|
-
};
|
|
2579
|
-
}));
|
|
2580
|
-
config.resolve.alias.push(...Object.keys(shared).filter((key) => !(isVinext && key === "react")).map((key) => {
|
|
2581
|
-
return command === "build" ? {
|
|
2582
|
-
find: new RegExp(`(.*${PREBUILD_TAG}.*)`),
|
|
2583
|
-
replacement: function($1) {
|
|
2584
|
-
const pkgName = assertModuleFound(PREBUILD_TAG, $1).name;
|
|
2585
|
-
return getPrebuildResolutionSource(pkgName, getPreBuildShareItem(pkgName));
|
|
2586
|
-
}
|
|
2587
|
-
} : {
|
|
2588
|
-
find: new RegExp(`(.*${PREBUILD_TAG}.*)`),
|
|
2589
|
-
replacement: "$1",
|
|
2590
|
-
async customResolver(source, importer) {
|
|
2591
|
-
const pkgName = assertModuleFound(PREBUILD_TAG, source).name;
|
|
2592
|
-
const importSource = getPrebuildResolutionSource(pkgName, getPreBuildShareItem(pkgName));
|
|
2593
|
-
const resolved = await this.resolve(importSource, importer);
|
|
2594
|
-
if (!resolved?.id) return;
|
|
2595
|
-
const result = resolved.id;
|
|
2596
|
-
if (_config && !result.includes(_config.cacheDir)) savePrebuild.set(pkgName, Promise.resolve(result));
|
|
2597
|
-
return await this.resolve(await savePrebuild.get(pkgName), importer);
|
|
2598
|
-
}
|
|
2599
|
-
};
|
|
2600
|
-
}));
|
|
2601
|
-
},
|
|
2602
|
-
configResolved(config) {
|
|
2603
|
-
_config = config;
|
|
2604
|
-
const isRolldown = getIsRolldown(this);
|
|
2605
|
-
Object.keys(shared).forEach((key) => {
|
|
2606
|
-
if (key.endsWith("/")) return;
|
|
2607
|
-
if (isVinext && key === "react") {
|
|
2608
|
-
addUsedShares(key);
|
|
2609
|
-
return;
|
|
2610
|
-
}
|
|
2611
|
-
writeLoadShareModule(key, shared[key], _command, isRolldown);
|
|
2612
|
-
if (shared[key].shareConfig.import !== false) writePreBuildLibPath(key, shared[key]);
|
|
2613
|
-
addUsedShares(key);
|
|
2614
|
-
});
|
|
2615
|
-
writeLocalSharedImportMap();
|
|
2616
|
-
}
|
|
2617
|
-
}];
|
|
2618
|
-
}
|
|
2619
|
-
//#endregion
|
|
2620
2795
|
//#region src/plugins/pluginVarRemoteEntry.ts
|
|
2621
2796
|
const VarRemoteEntry = () => {
|
|
2622
2797
|
const mfOptions = getNormalizeModuleFederationOptions();
|
|
@@ -2783,6 +2958,7 @@ var normalizeOptimizeDeps_default = {
|
|
|
2783
2958
|
};
|
|
2784
2959
|
//#endregion
|
|
2785
2960
|
//#region src/index.ts
|
|
2961
|
+
const patchedManualChunks = /* @__PURE__ */ new WeakSet();
|
|
2786
2962
|
const UNSAFE_JS_SOURCE_CHAR_MAP = {
|
|
2787
2963
|
"<": "\\u003C",
|
|
2788
2964
|
">": "\\u003E",
|
|
@@ -2827,6 +3003,10 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
2827
3003
|
config.optimizeDeps = config.optimizeDeps || {};
|
|
2828
3004
|
config.optimizeDeps.include = config.optimizeDeps.include || [];
|
|
2829
3005
|
config.optimizeDeps.include.push(virtualRuntimeInitStatus.getImportId());
|
|
3006
|
+
if (isRolldown) {
|
|
3007
|
+
config.optimizeDeps.exclude = config.optimizeDeps.exclude || [];
|
|
3008
|
+
config.optimizeDeps.exclude.push(...Object.keys(remotes || {}));
|
|
3009
|
+
}
|
|
2830
3010
|
}
|
|
2831
3011
|
for (const key of Object.keys(shared)) {
|
|
2832
3012
|
if (key.endsWith("/")) continue;
|
|
@@ -2857,6 +3037,7 @@ function federation(mfUserOptions) {
|
|
|
2857
3037
|
const remoteEntryId = getRemoteEntryId(options);
|
|
2858
3038
|
const virtualExposesId = getVirtualExposesId(options);
|
|
2859
3039
|
let command;
|
|
3040
|
+
let depsDir = "/node_modules/.vite/deps/";
|
|
2860
3041
|
return [
|
|
2861
3042
|
createEarlyVirtualModulesPlugin(options),
|
|
2862
3043
|
...isVinext ? [{
|
|
@@ -2884,6 +3065,11 @@ function federation(mfUserOptions) {
|
|
|
2884
3065
|
},
|
|
2885
3066
|
configResolved(config) {
|
|
2886
3067
|
VirtualModule.setRoot(config.root);
|
|
3068
|
+
const cacheDir = config.cacheDir;
|
|
3069
|
+
if (cacheDir) {
|
|
3070
|
+
const resolved = pathe.default.isAbsolute(cacheDir) ? cacheDir : pathe.default.resolve(config.root, cacheDir);
|
|
3071
|
+
depsDir = (0, vite.normalizePath)(pathe.default.join(resolved, "deps")) + "/";
|
|
3072
|
+
} else depsDir = (0, vite.normalizePath)(pathe.default.join(config.root, "node_modules", ".vite", "deps")) + "/";
|
|
2887
3073
|
VirtualModule.ensureVirtualPackageExists();
|
|
2888
3074
|
initVirtualModules(command, remoteEntryId);
|
|
2889
3075
|
}
|
|
@@ -2951,17 +3137,20 @@ function federation(mfUserOptions) {
|
|
|
2951
3137
|
let warnedAboutManualChunks = false;
|
|
2952
3138
|
const applyManualChunks = (output) => {
|
|
2953
3139
|
ensureCodeSplitting(output);
|
|
2954
|
-
|
|
3140
|
+
const isPatchedByPlugin = !!(output.manualChunks && patchedManualChunks.has(output.manualChunks));
|
|
3141
|
+
if (output.manualChunks && !isPatchedByPlugin && !warnedAboutManualChunks) {
|
|
2955
3142
|
warnedAboutManualChunks = true;
|
|
2956
3143
|
mfWarn("Ignoring `build.rollupOptions.output.manualChunks` because it conflicts with module federation. Module federation transforms shared dependency imports with top-level await, and grouping these transformed modules into a single chunk creates circular async dependencies that cause the application to silently hang.");
|
|
2957
3144
|
}
|
|
2958
|
-
|
|
3145
|
+
const mfManualChunks = function(id) {
|
|
2959
3146
|
if (id.includes(runtimeInitId)) return "runtimeInit";
|
|
2960
3147
|
if (id.includes("__loadShare__")) {
|
|
2961
3148
|
const match = id.match(/([^/\\]+__loadShare__[^/\\]+)/);
|
|
2962
3149
|
return match ? match[1] : "loadShare";
|
|
2963
3150
|
}
|
|
2964
3151
|
};
|
|
3152
|
+
patchedManualChunks.add(mfManualChunks);
|
|
3153
|
+
output.manualChunks = mfManualChunks;
|
|
2965
3154
|
};
|
|
2966
3155
|
config.build.rollupOptions = config.build.rollupOptions || {};
|
|
2967
3156
|
if (!Array.isArray(config.build.rollupOptions.output)) applyManualChunks(config.build.rollupOptions.output ||= {});
|
|
@@ -3145,7 +3334,7 @@ function federation(mfUserOptions) {
|
|
|
3145
3334
|
apply: "serve",
|
|
3146
3335
|
enforce: "post",
|
|
3147
3336
|
transform(code, id) {
|
|
3148
|
-
if (!id.
|
|
3337
|
+
if (!(0, vite.normalizePath)(id).split("?")[0].startsWith(depsDir)) return;
|
|
3149
3338
|
const initPattern = /\b(init_\w+__loadShare__\w+)\b/g;
|
|
3150
3339
|
const initFns = /* @__PURE__ */ new Set();
|
|
3151
3340
|
let match;
|
|
@@ -3198,37 +3387,55 @@ function federation(mfUserOptions) {
|
|
|
3198
3387
|
config.optimizeDeps.needsInterop.push(virtualDir);
|
|
3199
3388
|
config.optimizeDeps.needsInterop.push(getLocalSharedImportMapPath());
|
|
3200
3389
|
}
|
|
3390
|
+
const isAstro = hasPackageDependency("astro");
|
|
3201
3391
|
const resolvedTarget = options.target ?? (config.build?.ssr ? "node" : "web");
|
|
3392
|
+
const envTargetDefineValue = !options.target && isAstro ? "undefined" : JSON.stringify(resolvedTarget);
|
|
3202
3393
|
if (!config.define) config.define = {};
|
|
3203
|
-
if (!("ENV_TARGET" in config.define)) config.define["ENV_TARGET"] =
|
|
3394
|
+
if (!("ENV_TARGET" in config.define)) config.define["ENV_TARGET"] = envTargetDefineValue;
|
|
3204
3395
|
if (options.target && "ENV_TARGET" in config.define && config.define["ENV_TARGET"] !== JSON.stringify(options.target)) mfWarn(`ENV_TARGET define (${config.define["ENV_TARGET"]}) differs from target option ("${options.target}"). ENV_TARGET will not be overridden.`);
|
|
3205
3396
|
}
|
|
3206
3397
|
},
|
|
3207
3398
|
...Manifest(),
|
|
3208
3399
|
...VarRemoteEntry(),
|
|
3209
|
-
...
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
const
|
|
3218
|
-
const
|
|
3219
|
-
const
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3400
|
+
...(function() {
|
|
3401
|
+
let disablePreload = false;
|
|
3402
|
+
return Object.keys(options.exposes).length > 0 ? [{
|
|
3403
|
+
name: "module-federation-fix-preload",
|
|
3404
|
+
enforce: "post",
|
|
3405
|
+
apply: "build",
|
|
3406
|
+
config(_config, { command }) {
|
|
3407
|
+
const manifest = options.manifest;
|
|
3408
|
+
const isConsumerProject = Object.keys(options.exposes).length === 0;
|
|
3409
|
+
const getDefaultDisableAssetsAnalyze = (cfgCommand) => cfgCommand === "serve" && isConsumerProject && (typeof manifest !== "object" || !Object.prototype.hasOwnProperty.call(manifest, "disableAssetsAnalyze"));
|
|
3410
|
+
const getConfiguredDisableAssetsAnalyze = (cfgCommand) => {
|
|
3411
|
+
if (typeof manifest === "object" && manifest !== null) {
|
|
3412
|
+
if (Object.prototype.hasOwnProperty.call(manifest, "disableAssetsAnalyze")) return manifest.disableAssetsAnalyze === true;
|
|
3413
|
+
}
|
|
3414
|
+
return getDefaultDisableAssetsAnalyze(cfgCommand);
|
|
3415
|
+
};
|
|
3416
|
+
disablePreload = getConfiguredDisableAssetsAnalyze(command);
|
|
3417
|
+
},
|
|
3418
|
+
generateBundle(_, bundle) {
|
|
3419
|
+
if (disablePreload) return;
|
|
3420
|
+
for (const chunk of Object.values(bundle)) {
|
|
3421
|
+
if (chunk.type !== "chunk") continue;
|
|
3422
|
+
if (!chunk.code.includes("modulepreload")) continue;
|
|
3423
|
+
const chunkDir = pathe.default.dirname(chunk.fileName);
|
|
3424
|
+
const prefixToRoot = chunkDir === "." ? "" : `${pathe.default.relative(chunkDir, ".")}/`;
|
|
3425
|
+
const replacementExpr = prefixToRoot ? `${escapeUnsafeJsSourceChars(JSON.stringify(prefixToRoot))}+$1` : "$1";
|
|
3426
|
+
const replacement = `=function($1){return new URL(${replacementExpr},import.meta.url).href}`;
|
|
3427
|
+
const replaced = chunk.code.replace(/=\(?(\w+)(?:,\w+)?\)?\s*=>\s*["'`][^"'`]*["'`]\s*\+\s*\1/, replacement);
|
|
3428
|
+
if (replaced !== chunk.code) {
|
|
3429
|
+
chunk.code = replaced;
|
|
3430
|
+
continue;
|
|
3431
|
+
}
|
|
3432
|
+
chunk.code = chunk.code.replace(/=function\((\w+)(?:,\w+)?\)\{return\s*["'`][^"'`]*["'`]\s*\+\s*\1\s*\}/, replacement);
|
|
3433
|
+
chunk.code = chunk.code.replace(/=function\((\w+)(?:,\w+)?\)\{return new URL\("\.\.\/"\+\1,import\.meta\.url\)\.href\}/, replacement);
|
|
3434
|
+
chunk.code = chunk.code.replace(/new URL\("\.\.\/"\+(\w+),import\.meta\.url\)\.href/g, `new URL(${replacementExpr},import.meta.url).href`);
|
|
3225
3435
|
}
|
|
3226
|
-
chunk.code = chunk.code.replace(/=function\((\w+)(?:,\w+)?\)\{return\s*["'`][^"'`]*["'`]\s*\+\s*\1\s*\}/, replacement);
|
|
3227
|
-
chunk.code = chunk.code.replace(/=function\((\w+)(?:,\w+)?\)\{return new URL\("\.\.\/"\+\1,import\.meta\.url\)\.href\}/, replacement);
|
|
3228
|
-
chunk.code = chunk.code.replace(/new URL\("\.\.\/"\+(\w+),import\.meta\.url\)\.href/g, `new URL(${replacementExpr},import.meta.url).href`);
|
|
3229
3436
|
}
|
|
3230
|
-
}
|
|
3231
|
-
}
|
|
3437
|
+
}] : [];
|
|
3438
|
+
})()
|
|
3232
3439
|
];
|
|
3233
3440
|
}
|
|
3234
3441
|
//#endregion
|