@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.mjs
CHANGED
|
@@ -5,6 +5,7 @@ import { existsSync, mkdirSync, readFileSync, writeFile, writeFileSync } from "f
|
|
|
5
5
|
import { createRequire as createRequire$1 } from "module";
|
|
6
6
|
import * as path$1 from "pathe";
|
|
7
7
|
import path, { basename, dirname, join, parse, resolve } from "pathe";
|
|
8
|
+
import { normalizePath } from "vite";
|
|
8
9
|
import MagicString from "magic-string";
|
|
9
10
|
import { createFilter } from "@rollup/pluginutils";
|
|
10
11
|
import { normalizeOptions } from "@module-federation/sdk";
|
|
@@ -130,11 +131,13 @@ function removePathFromNpmPackage(packageString) {
|
|
|
130
131
|
return match ? match[0] : packageString;
|
|
131
132
|
}
|
|
132
133
|
/**
|
|
133
|
-
* Detect whether the current runtime is Vite 8+
|
|
134
|
-
*
|
|
134
|
+
* Detect whether the current runtime is Vite 8+ by checking for a Vite version flag
|
|
135
|
+
* on the plugin hook context, with Rolldown metadata kept as a compatibility fallback.
|
|
135
136
|
*/
|
|
136
137
|
function getIsRolldown(ctx) {
|
|
137
|
-
|
|
138
|
+
const viteVersion = ctx?.meta?.viteVersion;
|
|
139
|
+
const viteMajor = Number(String(viteVersion ?? "").split(".")[0]);
|
|
140
|
+
return Number.isFinite(viteMajor) && viteMajor >= 8 || !!ctx?.meta?.rolldownVersion;
|
|
138
141
|
}
|
|
139
142
|
function hasPackageDependency(dependencyName, cwd = packageDetectionCwd || process.cwd()) {
|
|
140
143
|
const cacheKey = getDependencyCacheKey(cwd, dependencyName);
|
|
@@ -203,17 +206,21 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry" }) => {
|
|
|
203
206
|
next();
|
|
204
207
|
});
|
|
205
208
|
},
|
|
206
|
-
transformIndexHtml
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
209
|
+
transformIndexHtml: {
|
|
210
|
+
order: "pre",
|
|
211
|
+
handler(c) {
|
|
212
|
+
if (!injectHtml()) return;
|
|
213
|
+
clientInjected = true;
|
|
214
|
+
const base = viteConfig.base.replace(/\/$/, "");
|
|
215
|
+
const stripBase = (p) => base && p.startsWith(base) ? p.slice(base.length) : p;
|
|
216
|
+
const html = rewriteEntryScripts(c, (originalSrc) => {
|
|
217
|
+
return `/@id/${DEV_HTML_PROXY_PREFIX}${new URLSearchParams({
|
|
218
|
+
init: sanitizeDevEntryPath(stripBase(devEntryPath)),
|
|
219
|
+
entry: originalSrc
|
|
220
|
+
}).toString()}`;
|
|
221
|
+
});
|
|
222
|
+
return html === c ? injectEntryScript(c, stripBase(devEntryPath)) : html;
|
|
223
|
+
}
|
|
217
224
|
},
|
|
218
225
|
resolveId(id) {
|
|
219
226
|
if (id.startsWith(DEV_HTML_PROXY_PREFIX)) return id;
|
|
@@ -783,13 +790,13 @@ function normalizeLibrary(library) {
|
|
|
783
790
|
if (!library) return void 0;
|
|
784
791
|
return library;
|
|
785
792
|
}
|
|
786
|
-
function normalizeManifest(manifest
|
|
793
|
+
function normalizeManifest(manifest) {
|
|
794
|
+
if (manifest === void 0) return;
|
|
787
795
|
if (typeof manifest === "boolean") return manifest;
|
|
788
|
-
return
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
}, manifest);
|
|
796
|
+
return {
|
|
797
|
+
...manifest,
|
|
798
|
+
fileName: manifest.fileName || "mf-manifest.json"
|
|
799
|
+
};
|
|
793
800
|
}
|
|
794
801
|
let config;
|
|
795
802
|
function getNormalizeModuleFederationOptions() {
|
|
@@ -1208,6 +1215,13 @@ function escapeGeneratedStringLiteral(value) {
|
|
|
1208
1215
|
}
|
|
1209
1216
|
});
|
|
1210
1217
|
}
|
|
1218
|
+
function isValidJsIdentifier(name) {
|
|
1219
|
+
return /^[$_\p{ID_Start}][$_\u200C\u200D\p{ID_Continue}]*$/u.test(name);
|
|
1220
|
+
}
|
|
1221
|
+
function isValidEsmExportName(name) {
|
|
1222
|
+
return !!name && name !== "default" && name !== "__esModule" && isValidJsIdentifier(name);
|
|
1223
|
+
}
|
|
1224
|
+
const JS_IDENTIFIER_PATTERN = `[\$_\\p{ID_Start}][\$_\\u200C\\u200D\\p{ID_Continue}]*`;
|
|
1211
1225
|
const localRequire = createRequire$1(import.meta.url);
|
|
1212
1226
|
function resolvePackageEntryFromProjectRoot(pkg) {
|
|
1213
1227
|
try {
|
|
@@ -1285,21 +1299,51 @@ function getPackageEsmEntryPath(pkg) {
|
|
|
1285
1299
|
}
|
|
1286
1300
|
}
|
|
1287
1301
|
function getEsmNamedExports(pkg) {
|
|
1302
|
+
let source = "";
|
|
1288
1303
|
try {
|
|
1289
1304
|
const entryPath = getPackageEsmEntryPath(pkg);
|
|
1290
1305
|
if (!entryPath) return [];
|
|
1291
1306
|
const { initSync, parse } = localRequire("es-module-lexer");
|
|
1292
1307
|
initSync();
|
|
1293
|
-
|
|
1294
|
-
|
|
1308
|
+
source = readFileSync(entryPath, "utf-8");
|
|
1309
|
+
const [, exports] = parse(source, entryPath);
|
|
1310
|
+
const names = exports.map((item) => item.n).filter((name) => isValidEsmExportName(name));
|
|
1311
|
+
const regexNames = getNamedExportsViaRegex(source);
|
|
1312
|
+
const filteredNames = names.filter((name) => name !== "type" || regexNames.includes(name));
|
|
1313
|
+
if (filteredNames.length > 0) return [...new Set([...filteredNames, ...regexNames])];
|
|
1314
|
+
return regexNames;
|
|
1295
1315
|
} catch {
|
|
1296
|
-
return [];
|
|
1316
|
+
return source ? getNamedExportsViaRegex(source) : [];
|
|
1297
1317
|
}
|
|
1298
1318
|
}
|
|
1319
|
+
function getNamedExportsViaRegex(source) {
|
|
1320
|
+
const names = /* @__PURE__ */ new Set();
|
|
1321
|
+
const declRegex = new RegExp(`export\\s+(?:async\\s+)?(?:function(?:\\*\\s*|\\s+\\*?\\s*)|const\\s+|let\\s+|var\\s+|class\\s+)(${JS_IDENTIFIER_PATTERN})`, "gu");
|
|
1322
|
+
let match;
|
|
1323
|
+
while ((match = declRegex.exec(source)) !== null) {
|
|
1324
|
+
const name = match[1];
|
|
1325
|
+
if (isValidEsmExportName(name)) names.add(name);
|
|
1326
|
+
}
|
|
1327
|
+
const listRegex = /export\s*\{([^}]+)\}/g;
|
|
1328
|
+
const typeOnlySpecifierRegex = new RegExp(`^type\\s+${JS_IDENTIFIER_PATTERN}(?:\\s+as\\s+${JS_IDENTIFIER_PATTERN})?$`, "u");
|
|
1329
|
+
const exportSpecifierRegex = new RegExp(`(?:\\S+\\s+as\\s+)?(${JS_IDENTIFIER_PATTERN})$`, "u");
|
|
1330
|
+
while ((match = listRegex.exec(source)) !== null) {
|
|
1331
|
+
const specifiers = match[1].split(",");
|
|
1332
|
+
for (const specifier of specifiers) {
|
|
1333
|
+
const trimmed = specifier.trim();
|
|
1334
|
+
if (typeOnlySpecifierRegex.test(trimmed)) continue;
|
|
1335
|
+
const asMatch = trimmed.match(exportSpecifierRegex);
|
|
1336
|
+
if (!asMatch) continue;
|
|
1337
|
+
const name = asMatch[1];
|
|
1338
|
+
if (isValidEsmExportName(name)) names.add(name);
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
return [...names];
|
|
1342
|
+
}
|
|
1299
1343
|
function getPackageNamedExports(pkg) {
|
|
1300
1344
|
try {
|
|
1301
1345
|
const mod = createRequire$1(new URL(`file://${path.join(getPackageDetectionCwd(), "package.json")}`))(pkg);
|
|
1302
|
-
return Object.keys(mod).filter((k) =>
|
|
1346
|
+
return Object.keys(mod).filter((k) => isValidEsmExportName(k));
|
|
1303
1347
|
} catch {
|
|
1304
1348
|
return getEsmNamedExports(pkg);
|
|
1305
1349
|
}
|
|
@@ -1307,11 +1351,14 @@ function getPackageNamedExports(pkg) {
|
|
|
1307
1351
|
function getLocalProviderImportPath(pkg) {
|
|
1308
1352
|
try {
|
|
1309
1353
|
const resolved = createRequire$1(new URL(`file://${path.join(getPackageDetectionCwd(), "package.json")}`)).resolve(pkg);
|
|
1310
|
-
return resolved
|
|
1354
|
+
return isWorkspaceFilePath(resolved) ? resolved : void 0;
|
|
1311
1355
|
} catch {
|
|
1312
1356
|
return;
|
|
1313
1357
|
}
|
|
1314
1358
|
}
|
|
1359
|
+
function isWorkspaceFilePath(resolved) {
|
|
1360
|
+
return !!resolved && !resolved.includes("/node_modules/") && !resolved.includes("\\node_modules\\");
|
|
1361
|
+
}
|
|
1315
1362
|
function tryResolveImportFromPackageRoot(pkg, root) {
|
|
1316
1363
|
try {
|
|
1317
1364
|
return createRequire$1(new URL(`file://${path.join(root, "package.json")}`)).resolve(pkg);
|
|
@@ -1388,11 +1435,15 @@ function writeLoadShareModule(pkg, shareItem, command, isRolldown) {
|
|
|
1388
1435
|
`, true);
|
|
1389
1436
|
return;
|
|
1390
1437
|
}
|
|
1391
|
-
const
|
|
1438
|
+
const isVinext = hasPackageDependency("vinext");
|
|
1439
|
+
const isAstro = hasPackageDependency("astro");
|
|
1440
|
+
const useSsrProviderFallback = (isVinext || isAstro) && command === "build" && pkg === "react";
|
|
1392
1441
|
const concreteSharedImportSource = getConcreteSharedImportSource(pkg, shareItem);
|
|
1393
1442
|
const sharedImportSource = concreteSharedImportSource || getPreBuildLibImportId(pkg);
|
|
1394
1443
|
const devImportSource = concreteSharedImportSource || pkg;
|
|
1395
|
-
const
|
|
1444
|
+
const localProviderPath = getLocalProviderImportPath(pkg);
|
|
1445
|
+
const isWorkspacePackage = isWorkspaceFilePath(localProviderPath) || isWorkspaceFilePath(concreteSharedImportSource);
|
|
1446
|
+
const providerImportId = localProviderPath || concreteSharedImportSource || sharedImportSource;
|
|
1396
1447
|
const namedExports = getPackageNamedExports(pkg);
|
|
1397
1448
|
let exportLine;
|
|
1398
1449
|
if (namedExports.length > 0) {
|
|
@@ -1400,9 +1451,11 @@ function writeLoadShareModule(pkg, shareItem, command, isRolldown) {
|
|
|
1400
1451
|
const namedExportLine = `export { ${namedExports.map((name, i) => `__mf_${i} as ${name}`).join(", ")} };`;
|
|
1401
1452
|
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(", ")} });`;
|
|
1402
1453
|
} else exportLine = useESM ? `export default exportModule.default ?? exportModule\n export * from ${escapeGeneratedStringLiteral(sharedImportSource)}` : "module.exports = exportModule";
|
|
1454
|
+
const prebuildImportLine = isWorkspacePackage && command !== "build" ? "" : `import ${escapeGeneratedStringLiteral(sharedImportSource)};`;
|
|
1455
|
+
const devDynamicImportLine = isWorkspacePackage ? "" : command !== "build" ? `;() => import(${escapeGeneratedStringLiteral(devImportSource)}).catch(() => {});` : "";
|
|
1403
1456
|
loadShareCacheMap[pkg].writeSync(`
|
|
1404
|
-
|
|
1405
|
-
${
|
|
1457
|
+
${prebuildImportLine}
|
|
1458
|
+
${devDynamicImportLine}
|
|
1406
1459
|
${importLine}
|
|
1407
1460
|
${useSsrProviderFallback ? `const providerModulePromise = typeof window === "undefined"
|
|
1408
1461
|
? import(${escapeGeneratedStringLiteral(providerImportId)})
|
|
@@ -1443,6 +1496,8 @@ function writeLocalSharedImportMap() {
|
|
|
1443
1496
|
}
|
|
1444
1497
|
function generateLocalSharedImportMap() {
|
|
1445
1498
|
const isVinext = hasPackageDependency("vinext");
|
|
1499
|
+
const isAstro = hasPackageDependency("astro");
|
|
1500
|
+
const useDirectReactImport = isVinext || isAstro;
|
|
1446
1501
|
const options = getNormalizeModuleFederationOptions();
|
|
1447
1502
|
return `
|
|
1448
1503
|
import {loadShare} from "@module-federation/runtime";
|
|
@@ -1451,7 +1506,7 @@ function generateLocalSharedImportMap() {
|
|
|
1451
1506
|
const shareItem = getNormalizeShareItem(pkg);
|
|
1452
1507
|
return `
|
|
1453
1508
|
${JSON.stringify(pkg)}: async () => {
|
|
1454
|
-
${shareItem?.shareConfig.import === false ? `throw new Error(\`[Module Federation] Shared module '\${${JSON.stringify(pkg)}}' must be provided by host\`);` :
|
|
1509
|
+
${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");
|
|
1455
1510
|
return pkg;` : `let pkg = await import(${JSON.stringify(getSharedImportSource(pkg, shareItem))});
|
|
1456
1511
|
return pkg;`}
|
|
1457
1512
|
}
|
|
@@ -1476,7 +1531,7 @@ function generateLocalSharedImportMap() {
|
|
|
1476
1531
|
usedShared[${JSON.stringify(key)}].loaded = true
|
|
1477
1532
|
const {${JSON.stringify(key)}: pkgDynamicImport} = importMap
|
|
1478
1533
|
const res = await pkgDynamicImport()
|
|
1479
|
-
const exportModule = ${JSON.stringify(
|
|
1534
|
+
const exportModule = ${JSON.stringify(useDirectReactImport)} && ${JSON.stringify(key)} === "react"
|
|
1480
1535
|
? (res?.default ?? res)
|
|
1481
1536
|
: {...res}
|
|
1482
1537
|
// All npm packages pre-built by vite will be converted to esm
|
|
@@ -1791,7 +1846,7 @@ const buildFileToShareKeyMap = async (shareKeys, resolveFn) => {
|
|
|
1791
1846
|
* @returns The resolved public path
|
|
1792
1847
|
*/
|
|
1793
1848
|
function resolvePublicPath(options, viteBase, originalBase) {
|
|
1794
|
-
if (options.publicPath) return options.publicPath;
|
|
1849
|
+
if (options.publicPath && options.publicPath !== "auto") return options.publicPath;
|
|
1795
1850
|
if (originalBase === "") return "auto";
|
|
1796
1851
|
if (viteBase) return viteBase.replace(/\/?$/, "/");
|
|
1797
1852
|
return "auto";
|
|
@@ -1801,9 +1856,17 @@ function resolvePublicPath(options, viteBase, originalBase) {
|
|
|
1801
1856
|
const Manifest = () => {
|
|
1802
1857
|
const mfOptions = getNormalizeModuleFederationOptions();
|
|
1803
1858
|
const { name, filename, getPublicPath, manifest: manifestOptions, varFilename } = mfOptions;
|
|
1804
|
-
let mfManifestName = "";
|
|
1805
|
-
|
|
1806
|
-
|
|
1859
|
+
let mfManifestName = manifestOptions === true ? "mf-manifest.json" : typeof manifestOptions === "object" ? path$1.join(manifestOptions?.filePath || "", manifestOptions?.fileName || "mf-manifest.json") : void 0;
|
|
1860
|
+
let mfManifestStatsName = mfManifestName ? getStatsFileName(mfManifestName) : void 0;
|
|
1861
|
+
const isConsumerProject = Object.keys(mfOptions.exposes).length === 0;
|
|
1862
|
+
let disableAssetsAnalyze = false;
|
|
1863
|
+
const getDefaultDisableAssetsAnalyze = (command) => command === "serve" && isConsumerProject && (typeof manifestOptions !== "object" || !Object.prototype.hasOwnProperty.call(manifestOptions, "disableAssetsAnalyze"));
|
|
1864
|
+
const getConfiguredDisableAssetsAnalyze = (command) => {
|
|
1865
|
+
if (typeof manifestOptions === "object" && manifestOptions !== null) {
|
|
1866
|
+
if (Object.prototype.hasOwnProperty.call(manifestOptions, "disableAssetsAnalyze")) return manifestOptions.disableAssetsAnalyze === true;
|
|
1867
|
+
}
|
|
1868
|
+
return getDefaultDisableAssetsAnalyze(command);
|
|
1869
|
+
};
|
|
1807
1870
|
let root;
|
|
1808
1871
|
let remoteEntryFile;
|
|
1809
1872
|
let publicPath;
|
|
@@ -1838,7 +1901,7 @@ const Manifest = () => {
|
|
|
1838
1901
|
res.setHeader("Content-Type", "application/json");
|
|
1839
1902
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
1840
1903
|
res.end(JSON.stringify({
|
|
1841
|
-
...generateMFManifest({}),
|
|
1904
|
+
...generateMFManifest({}, disableAssetsAnalyze),
|
|
1842
1905
|
id: name,
|
|
1843
1906
|
name,
|
|
1844
1907
|
metaData: {
|
|
@@ -1879,9 +1942,10 @@ const Manifest = () => {
|
|
|
1879
1942
|
name: "module-federation-manifest",
|
|
1880
1943
|
enforce: "post",
|
|
1881
1944
|
config(config, { command }) {
|
|
1882
|
-
if (!config.build) config.build = {};
|
|
1883
|
-
if (!config.build.manifest) config.build.manifest = config.build.manifest || !!manifestOptions;
|
|
1884
1945
|
_command = command;
|
|
1946
|
+
if (!config.build) config.build = {};
|
|
1947
|
+
if (!config.build.manifest) config.build.manifest = config.build.manifest || !!mfManifestName;
|
|
1948
|
+
disableAssetsAnalyze = getConfiguredDisableAssetsAnalyze(command);
|
|
1885
1949
|
_originalConfigBase = config.base;
|
|
1886
1950
|
},
|
|
1887
1951
|
configResolved(config) {
|
|
@@ -1895,28 +1959,35 @@ const Manifest = () => {
|
|
|
1895
1959
|
let filesMap = {};
|
|
1896
1960
|
const foundRemoteEntryFile = findRemoteEntryFile(mfOptions.filename, bundle);
|
|
1897
1961
|
if (foundRemoteEntryFile) remoteEntryFile = foundRemoteEntryFile;
|
|
1898
|
-
const allCssAssets = mfOptions.bundleAllCSS ? collectCssAssets(bundle) : /* @__PURE__ */ new Set();
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
const
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1962
|
+
const allCssAssets = mfOptions.bundleAllCSS && !disableAssetsAnalyze ? collectCssAssets(bundle) : /* @__PURE__ */ new Set();
|
|
1963
|
+
if (!disableAssetsAnalyze) {
|
|
1964
|
+
const exposesModules = Object.keys(mfOptions.exposes).map((item) => mfOptions.exposes[item].import);
|
|
1965
|
+
processModuleAssets(bundle, filesMap, (modulePath) => {
|
|
1966
|
+
const absoluteModulePath = path$1.resolve(root, modulePath);
|
|
1967
|
+
return exposesModules.find((exposeModule) => {
|
|
1968
|
+
const exposePath = path$1.resolve(root, exposeModule);
|
|
1969
|
+
if (absoluteModulePath === exposePath) return true;
|
|
1970
|
+
const getPathWithoutKnownExt = (filePath) => {
|
|
1971
|
+
const ext = path$1.extname(filePath);
|
|
1972
|
+
return JS_EXTENSIONS.includes(ext) ? path$1.join(path$1.dirname(filePath), path$1.basename(filePath, ext)) : filePath;
|
|
1973
|
+
};
|
|
1974
|
+
return getPathWithoutKnownExt(absoluteModulePath) === getPathWithoutKnownExt(exposePath);
|
|
1975
|
+
});
|
|
1910
1976
|
});
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1977
|
+
const fileToShareKey = await buildFileToShareKeyMap(getUsedShares(), this.resolve.bind(this));
|
|
1978
|
+
processModuleAssets(bundle, filesMap, (modulePath) => fileToShareKey.get(modulePath));
|
|
1979
|
+
if (mfOptions.bundleAllCSS) addCssAssetsToAllExports(filesMap, allCssAssets);
|
|
1980
|
+
filesMap = deduplicateAssets(filesMap);
|
|
1981
|
+
}
|
|
1916
1982
|
this.emitFile({
|
|
1917
1983
|
type: "asset",
|
|
1918
1984
|
fileName: mfManifestName,
|
|
1919
|
-
source: JSON.stringify(generateMFManifest(filesMap))
|
|
1985
|
+
source: JSON.stringify(generateMFManifest(filesMap, disableAssetsAnalyze))
|
|
1986
|
+
});
|
|
1987
|
+
if (mfManifestStatsName) this.emitFile({
|
|
1988
|
+
type: "asset",
|
|
1989
|
+
fileName: mfManifestStatsName,
|
|
1990
|
+
source: JSON.stringify(generateMFStats(filesMap, bundle, disableAssetsAnalyze))
|
|
1920
1991
|
});
|
|
1921
1992
|
}
|
|
1922
1993
|
}];
|
|
@@ -1925,7 +1996,7 @@ const Manifest = () => {
|
|
|
1925
1996
|
* @param preloadMap - Map of module assets to include
|
|
1926
1997
|
* @returns Complete manifest object
|
|
1927
1998
|
*/
|
|
1928
|
-
function generateMFManifest(preloadMap) {
|
|
1999
|
+
function generateMFManifest(preloadMap, disableAssetsAnalyze = false) {
|
|
1929
2000
|
const options = getNormalizeModuleFederationOptions();
|
|
1930
2001
|
const { name, varFilename } = options;
|
|
1931
2002
|
const remoteEntry = {
|
|
@@ -1951,6 +2022,7 @@ const Manifest = () => {
|
|
|
1951
2022
|
id: `${name}:${shareKey}`,
|
|
1952
2023
|
name: shareKey,
|
|
1953
2024
|
version: shareItem.version,
|
|
2025
|
+
singleton: shareItem.shareConfig.singleton,
|
|
1954
2026
|
requiredVersion: shareItem.shareConfig.requiredVersion,
|
|
1955
2027
|
assets: {
|
|
1956
2028
|
js: {
|
|
@@ -2004,12 +2076,33 @@ const Manifest = () => {
|
|
|
2004
2076
|
pluginVersion: "0.2.5",
|
|
2005
2077
|
...!!getPublicPath ? { getPublicPath } : { publicPath }
|
|
2006
2078
|
},
|
|
2007
|
-
shared,
|
|
2079
|
+
...disableAssetsAnalyze ? {} : { shared },
|
|
2008
2080
|
remotes,
|
|
2009
|
-
exposes
|
|
2081
|
+
...disableAssetsAnalyze ? {} : { exposes }
|
|
2082
|
+
};
|
|
2083
|
+
}
|
|
2084
|
+
function generateMFStats(preloadMap, bundle, disableAssetsAnalyze = false) {
|
|
2085
|
+
const baseManifest = generateMFManifest(preloadMap, disableAssetsAnalyze);
|
|
2086
|
+
const bundleSummary = Object.entries(bundle).map(([fileName, chunkOrAsset]) => ({
|
|
2087
|
+
fileName,
|
|
2088
|
+
type: chunkOrAsset.type,
|
|
2089
|
+
isEntry: chunkOrAsset.isEntry || false,
|
|
2090
|
+
size: typeof chunkOrAsset.code === "string" ? chunkOrAsset.code.length : chunkOrAsset.source?.length || chunkOrAsset.source?.byteLength || void 0
|
|
2091
|
+
}));
|
|
2092
|
+
return {
|
|
2093
|
+
...baseManifest,
|
|
2094
|
+
buildOutput: bundleSummary,
|
|
2095
|
+
...disableAssetsAnalyze ? {} : { assetAnalysis: preloadMap }
|
|
2010
2096
|
};
|
|
2011
2097
|
}
|
|
2012
2098
|
};
|
|
2099
|
+
function getStatsFileName(manifestFileName) {
|
|
2100
|
+
const parsed = path$1.parse(manifestFileName);
|
|
2101
|
+
const fileExt = parsed.ext || ".json";
|
|
2102
|
+
const baseName = parsed.ext ? parsed.name : parsed.base;
|
|
2103
|
+
const fileName = `${baseName === "mf-manifest" ? "mf" : baseName}-stats${fileExt}`;
|
|
2104
|
+
return parsed.dir ? path$1.join(parsed.dir, fileName) : fileName;
|
|
2105
|
+
}
|
|
2013
2106
|
//#endregion
|
|
2014
2107
|
//#region src/plugins/pluginModuleParseEnd.ts
|
|
2015
2108
|
let _resolve, _parseTimeout;
|
|
@@ -2213,6 +2306,130 @@ function pluginProxyRemotes_default(options) {
|
|
|
2213
2306
|
};
|
|
2214
2307
|
}
|
|
2215
2308
|
//#endregion
|
|
2309
|
+
//#region src/utils/PromiseStore.ts
|
|
2310
|
+
/**
|
|
2311
|
+
* example:
|
|
2312
|
+
* const store = new PromiseStore<number>();
|
|
2313
|
+
* store.get("example").then((result) => {
|
|
2314
|
+
* console.log("Result from example:", result); // 42
|
|
2315
|
+
* });
|
|
2316
|
+
* setTimeout(() => {
|
|
2317
|
+
* store.set("example", Promise.resolve(42));
|
|
2318
|
+
* }, 2000);
|
|
2319
|
+
*/
|
|
2320
|
+
var PromiseStore = class {
|
|
2321
|
+
constructor() {
|
|
2322
|
+
this.promiseMap = /* @__PURE__ */ new Map();
|
|
2323
|
+
this.resolveMap = /* @__PURE__ */ new Map();
|
|
2324
|
+
}
|
|
2325
|
+
set(id, promise) {
|
|
2326
|
+
if (this.resolveMap.has(id)) {
|
|
2327
|
+
promise.then(this.resolveMap.get(id));
|
|
2328
|
+
this.resolveMap.delete(id);
|
|
2329
|
+
}
|
|
2330
|
+
this.promiseMap.set(id, promise);
|
|
2331
|
+
}
|
|
2332
|
+
get(id) {
|
|
2333
|
+
if (this.promiseMap.has(id)) return this.promiseMap.get(id);
|
|
2334
|
+
const pendingPromise = new Promise((resolve) => {
|
|
2335
|
+
this.resolveMap.set(id, resolve);
|
|
2336
|
+
});
|
|
2337
|
+
this.promiseMap.set(id, pendingPromise);
|
|
2338
|
+
return pendingPromise;
|
|
2339
|
+
}
|
|
2340
|
+
};
|
|
2341
|
+
//#endregion
|
|
2342
|
+
//#region src/plugins/pluginProxySharedModule_preBuild.ts
|
|
2343
|
+
function getPrebuildResolutionSource(pkgName, shareItem) {
|
|
2344
|
+
return getConcreteSharedImportSource(pkgName, shareItem) || pkgName;
|
|
2345
|
+
}
|
|
2346
|
+
function proxySharedModule(options) {
|
|
2347
|
+
const { shared = {} } = options;
|
|
2348
|
+
let _config;
|
|
2349
|
+
let _command = "serve";
|
|
2350
|
+
let useDirectReactImport = false;
|
|
2351
|
+
const savePrebuild = new PromiseStore();
|
|
2352
|
+
return [{
|
|
2353
|
+
name: "generateLocalSharedImportMap",
|
|
2354
|
+
enforce: "post",
|
|
2355
|
+
load(id) {
|
|
2356
|
+
if (id.includes(getLocalSharedImportMapPath())) return parsePromise.then((_) => generateLocalSharedImportMap());
|
|
2357
|
+
},
|
|
2358
|
+
transform(_, id) {
|
|
2359
|
+
if (id.includes(getLocalSharedImportMapPath())) return mapCodeToCodeWithSourcemap(parsePromise.then((_) => generateLocalSharedImportMap()));
|
|
2360
|
+
}
|
|
2361
|
+
}, {
|
|
2362
|
+
name: "proxyPreBuildShared",
|
|
2363
|
+
enforce: "post",
|
|
2364
|
+
config(config, { command }) {
|
|
2365
|
+
setPackageDetectionCwd(config.root || process.cwd());
|
|
2366
|
+
const isVinext = hasPackageDependency("vinext");
|
|
2367
|
+
const isAstro = hasPackageDependency("astro");
|
|
2368
|
+
const isRolldown = getIsRolldown(this);
|
|
2369
|
+
_command = command;
|
|
2370
|
+
useDirectReactImport = isVinext || isAstro;
|
|
2371
|
+
config.resolve.alias.push(...Object.keys(shared).filter((key) => !(useDirectReactImport && key === "react")).map((key) => {
|
|
2372
|
+
const keyBase = key.endsWith("/") ? key.slice(0, -1) : key;
|
|
2373
|
+
const escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2374
|
+
const escapedKeyBase = escapeRegex(keyBase);
|
|
2375
|
+
const pattern = key.endsWith("/") ? `^(${escapedKeyBase}(?:\\/.*)?)$` : `^(${escapedKeyBase})$`;
|
|
2376
|
+
return {
|
|
2377
|
+
find: new RegExp(pattern),
|
|
2378
|
+
replacement: "$1",
|
|
2379
|
+
customResolver(source, importer) {
|
|
2380
|
+
if (/\.css$/.test(source)) return;
|
|
2381
|
+
if (useDirectReactImport && source === "react") return;
|
|
2382
|
+
if (importer && importer.includes("localSharedImportMap")) return;
|
|
2383
|
+
if (key.endsWith("/") && source !== key.slice(0, -1)) return;
|
|
2384
|
+
const loadSharePath = getLoadShareModulePath(source, isRolldown, command);
|
|
2385
|
+
writeLoadShareModule(source, shared[key], command, isRolldown);
|
|
2386
|
+
if (shared[key].shareConfig.import !== false) writePreBuildLibPath(source, shared[key]);
|
|
2387
|
+
addUsedShares(source);
|
|
2388
|
+
writeLocalSharedImportMap();
|
|
2389
|
+
return this.resolve(loadSharePath, importer);
|
|
2390
|
+
}
|
|
2391
|
+
};
|
|
2392
|
+
}));
|
|
2393
|
+
config.resolve.alias.push(...Object.keys(shared).filter((key) => !(useDirectReactImport && key === "react")).map((key) => {
|
|
2394
|
+
return command === "build" ? {
|
|
2395
|
+
find: new RegExp(`(.*${PREBUILD_TAG}.*)`),
|
|
2396
|
+
replacement: function($1) {
|
|
2397
|
+
const pkgName = assertModuleFound(PREBUILD_TAG, $1).name;
|
|
2398
|
+
return getPrebuildResolutionSource(pkgName, getPreBuildShareItem(pkgName));
|
|
2399
|
+
}
|
|
2400
|
+
} : {
|
|
2401
|
+
find: new RegExp(`(.*${PREBUILD_TAG}.*)`),
|
|
2402
|
+
replacement: "$1",
|
|
2403
|
+
async customResolver(source, importer) {
|
|
2404
|
+
const pkgName = assertModuleFound(PREBUILD_TAG, source).name;
|
|
2405
|
+
const importSource = getPrebuildResolutionSource(pkgName, getPreBuildShareItem(pkgName));
|
|
2406
|
+
const resolved = await this.resolve(importSource, importer);
|
|
2407
|
+
if (!resolved?.id) return;
|
|
2408
|
+
const result = resolved.id;
|
|
2409
|
+
if (_config && !result.includes(_config.cacheDir)) savePrebuild.set(pkgName, Promise.resolve(result));
|
|
2410
|
+
return await this.resolve(await savePrebuild.get(pkgName), importer);
|
|
2411
|
+
}
|
|
2412
|
+
};
|
|
2413
|
+
}));
|
|
2414
|
+
},
|
|
2415
|
+
configResolved(config) {
|
|
2416
|
+
_config = config;
|
|
2417
|
+
const isRolldown = getIsRolldown(this);
|
|
2418
|
+
Object.keys(shared).forEach((key) => {
|
|
2419
|
+
if (key.endsWith("/")) return;
|
|
2420
|
+
if (useDirectReactImport && key === "react") {
|
|
2421
|
+
addUsedShares(key);
|
|
2422
|
+
return;
|
|
2423
|
+
}
|
|
2424
|
+
writeLoadShareModule(key, shared[key], _command, isRolldown);
|
|
2425
|
+
if (shared[key].shareConfig.import !== false) writePreBuildLibPath(key, shared[key]);
|
|
2426
|
+
addUsedShares(key);
|
|
2427
|
+
});
|
|
2428
|
+
writeLocalSharedImportMap();
|
|
2429
|
+
}
|
|
2430
|
+
}];
|
|
2431
|
+
}
|
|
2432
|
+
//#endregion
|
|
2216
2433
|
//#region src/plugins/pluginRemoteNamedExports.ts
|
|
2217
2434
|
/**
|
|
2218
2435
|
* Transforms consumer-side imports of remote modules so that named exports
|
|
@@ -2235,6 +2452,7 @@ function pluginProxyRemotes_default(options) {
|
|
|
2235
2452
|
* build time. Use explicit named re-exports instead.
|
|
2236
2453
|
*/
|
|
2237
2454
|
const JS_EXTENSIONS_RE = /\.(?:[mc]?[jt]sx?|vue|svelte)(?:\?|$)/;
|
|
2455
|
+
const REGEX_FALLBACK_EXTENSIONS_RE = /\.(?:[mc]?[jt]sx?)(?:\?|$)/;
|
|
2238
2456
|
function wrapDynamicImport(original) {
|
|
2239
2457
|
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})`;
|
|
2240
2458
|
}
|
|
@@ -2444,18 +2662,96 @@ async function collectFromEsLexer(code, isRemoteImport) {
|
|
|
2444
2662
|
}
|
|
2445
2663
|
return result;
|
|
2446
2664
|
}
|
|
2665
|
+
function collectFromRegex(code, isRemoteImport) {
|
|
2666
|
+
const result = [];
|
|
2667
|
+
for (const match of code.matchAll(/^\s*import\s+([\s\S]*?)\s+from\s+(['"])([^'"]+)\2\s*;?/gm)) {
|
|
2668
|
+
const [full, specifiersPartRaw, , source] = match;
|
|
2669
|
+
if (!isRemoteImport(source)) continue;
|
|
2670
|
+
const specifiersPart = specifiersPartRaw.trim();
|
|
2671
|
+
if (/^type\s/.test(specifiersPart)) continue;
|
|
2672
|
+
const nsMatch = specifiersPart.match(/^\*\s+as\s+(\w+)$/);
|
|
2673
|
+
if (nsMatch) {
|
|
2674
|
+
result.push({
|
|
2675
|
+
kind: "static",
|
|
2676
|
+
source,
|
|
2677
|
+
start: match.index,
|
|
2678
|
+
end: match.index + full.length,
|
|
2679
|
+
named: [],
|
|
2680
|
+
namespaceLocal: nsMatch[1]
|
|
2681
|
+
});
|
|
2682
|
+
continue;
|
|
2683
|
+
}
|
|
2684
|
+
const braceMatch = specifiersPart.match(/\{([^}]*)\}/);
|
|
2685
|
+
if (!braceMatch) continue;
|
|
2686
|
+
const namedSpecifiers = braceMatch[1].split(",").map((s) => s.trim()).filter((s) => s.length > 0 && !s.startsWith("type "));
|
|
2687
|
+
if (namedSpecifiers.length === 0) continue;
|
|
2688
|
+
const defaultMatch = specifiersPart.match(/^(\w+)\s*,/);
|
|
2689
|
+
const named = namedSpecifiers.map((s) => {
|
|
2690
|
+
const asMatch = s.match(/^(\w+)\s+as\s+(\w+)$/);
|
|
2691
|
+
return {
|
|
2692
|
+
imported: asMatch ? asMatch[1] : s,
|
|
2693
|
+
local: asMatch ? asMatch[2] : s
|
|
2694
|
+
};
|
|
2695
|
+
});
|
|
2696
|
+
result.push({
|
|
2697
|
+
kind: "static",
|
|
2698
|
+
source,
|
|
2699
|
+
start: match.index,
|
|
2700
|
+
end: match.index + full.length,
|
|
2701
|
+
named,
|
|
2702
|
+
defaultLocal: defaultMatch?.[1]
|
|
2703
|
+
});
|
|
2704
|
+
}
|
|
2705
|
+
for (const match of code.matchAll(/^\s*export\s+\{([\s\S]*?)\}\s+from\s+(['"])([^'"]+)\2\s*;?/gm)) {
|
|
2706
|
+
const [full, specifiersRaw, , source] = match;
|
|
2707
|
+
if (!isRemoteImport(source)) continue;
|
|
2708
|
+
const specs = specifiersRaw.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
2709
|
+
if (specs.length === 0) continue;
|
|
2710
|
+
result.push({
|
|
2711
|
+
kind: "reexport",
|
|
2712
|
+
source,
|
|
2713
|
+
start: match.index,
|
|
2714
|
+
end: match.index + full.length,
|
|
2715
|
+
specifiers: specs.map((s) => {
|
|
2716
|
+
const asMatch = s.match(/^(\w+)\s+as\s+(\w+)$/);
|
|
2717
|
+
return {
|
|
2718
|
+
local: asMatch ? asMatch[1] : s,
|
|
2719
|
+
exported: asMatch ? asMatch[2] : s
|
|
2720
|
+
};
|
|
2721
|
+
})
|
|
2722
|
+
});
|
|
2723
|
+
}
|
|
2724
|
+
for (const match of code.matchAll(/^\s*export\s+\*\s+from\s+(['"])([^'"]+)\1\s*;?/gm)) {
|
|
2725
|
+
const [full, , source] = match;
|
|
2726
|
+
if (!isRemoteImport(source)) continue;
|
|
2727
|
+
result.push({
|
|
2728
|
+
kind: "export-all",
|
|
2729
|
+
source,
|
|
2730
|
+
start: match.index,
|
|
2731
|
+
end: match.index + full.length
|
|
2732
|
+
});
|
|
2733
|
+
}
|
|
2734
|
+
for (const match of code.matchAll(/import\(\s*(['"])([^'"]+)\1\s*\)/g)) {
|
|
2735
|
+
const [full, , source] = match;
|
|
2736
|
+
if (!isRemoteImport(source)) continue;
|
|
2737
|
+
result.push({
|
|
2738
|
+
kind: "dynamic",
|
|
2739
|
+
start: match.index,
|
|
2740
|
+
end: match.index + full.length,
|
|
2741
|
+
originalText: full
|
|
2742
|
+
});
|
|
2743
|
+
}
|
|
2744
|
+
return result.length > 0 ? result : void 0;
|
|
2745
|
+
}
|
|
2447
2746
|
function pluginRemoteNamedExports(options) {
|
|
2448
2747
|
const remoteNames = Object.keys(options.remotes);
|
|
2449
|
-
let rolldown;
|
|
2450
2748
|
function isRemoteImport(source) {
|
|
2451
|
-
return remoteNames.some((name) => source === name || source.startsWith(name + "/"));
|
|
2749
|
+
return remoteNames.some((name) => source === name || source.startsWith(name + "/")) || source.includes("__loadRemote__");
|
|
2452
2750
|
}
|
|
2453
2751
|
return {
|
|
2454
2752
|
name: "module-federation-remote-named-exports",
|
|
2455
|
-
enforce: "
|
|
2753
|
+
enforce: "post",
|
|
2456
2754
|
async transform(code, id) {
|
|
2457
|
-
rolldown ??= getIsRolldown(this);
|
|
2458
|
-
if (!rolldown) return;
|
|
2459
2755
|
if (remoteNames.length === 0) return;
|
|
2460
2756
|
if (id.includes("__loadRemote__") || id.includes("__loadShare__")) return;
|
|
2461
2757
|
if (!JS_EXTENSIONS_RE.test(id)) return;
|
|
@@ -2466,134 +2762,13 @@ function pluginRemoteNamedExports(options) {
|
|
|
2466
2762
|
} catch {
|
|
2467
2763
|
imports = await collectFromEsLexer(code, isRemoteImport);
|
|
2468
2764
|
}
|
|
2765
|
+
if ((!imports || imports.length === 0) && REGEX_FALLBACK_EXTENSIONS_RE.test(id)) imports = collectFromRegex(code, isRemoteImport);
|
|
2469
2766
|
if (!imports) return;
|
|
2470
2767
|
return applyRewrites(code, imports, id);
|
|
2471
2768
|
}
|
|
2472
2769
|
};
|
|
2473
2770
|
}
|
|
2474
2771
|
//#endregion
|
|
2475
|
-
//#region src/utils/PromiseStore.ts
|
|
2476
|
-
/**
|
|
2477
|
-
* example:
|
|
2478
|
-
* const store = new PromiseStore<number>();
|
|
2479
|
-
* store.get("example").then((result) => {
|
|
2480
|
-
* console.log("Result from example:", result); // 42
|
|
2481
|
-
* });
|
|
2482
|
-
* setTimeout(() => {
|
|
2483
|
-
* store.set("example", Promise.resolve(42));
|
|
2484
|
-
* }, 2000);
|
|
2485
|
-
*/
|
|
2486
|
-
var PromiseStore = class {
|
|
2487
|
-
constructor() {
|
|
2488
|
-
this.promiseMap = /* @__PURE__ */ new Map();
|
|
2489
|
-
this.resolveMap = /* @__PURE__ */ new Map();
|
|
2490
|
-
}
|
|
2491
|
-
set(id, promise) {
|
|
2492
|
-
if (this.resolveMap.has(id)) {
|
|
2493
|
-
promise.then(this.resolveMap.get(id));
|
|
2494
|
-
this.resolveMap.delete(id);
|
|
2495
|
-
}
|
|
2496
|
-
this.promiseMap.set(id, promise);
|
|
2497
|
-
}
|
|
2498
|
-
get(id) {
|
|
2499
|
-
if (this.promiseMap.has(id)) return this.promiseMap.get(id);
|
|
2500
|
-
const pendingPromise = new Promise((resolve) => {
|
|
2501
|
-
this.resolveMap.set(id, resolve);
|
|
2502
|
-
});
|
|
2503
|
-
this.promiseMap.set(id, pendingPromise);
|
|
2504
|
-
return pendingPromise;
|
|
2505
|
-
}
|
|
2506
|
-
};
|
|
2507
|
-
//#endregion
|
|
2508
|
-
//#region src/plugins/pluginProxySharedModule_preBuild.ts
|
|
2509
|
-
function getPrebuildResolutionSource(pkgName, shareItem) {
|
|
2510
|
-
return getConcreteSharedImportSource(pkgName, shareItem) || pkgName;
|
|
2511
|
-
}
|
|
2512
|
-
function proxySharedModule(options) {
|
|
2513
|
-
const { shared = {} } = options;
|
|
2514
|
-
let _config;
|
|
2515
|
-
let _command = "serve";
|
|
2516
|
-
let isVinext = false;
|
|
2517
|
-
const savePrebuild = new PromiseStore();
|
|
2518
|
-
return [{
|
|
2519
|
-
name: "generateLocalSharedImportMap",
|
|
2520
|
-
enforce: "post",
|
|
2521
|
-
load(id) {
|
|
2522
|
-
if (id.includes(getLocalSharedImportMapPath())) return parsePromise.then((_) => generateLocalSharedImportMap());
|
|
2523
|
-
},
|
|
2524
|
-
transform(_, id) {
|
|
2525
|
-
if (id.includes(getLocalSharedImportMapPath())) return mapCodeToCodeWithSourcemap(parsePromise.then((_) => generateLocalSharedImportMap()));
|
|
2526
|
-
}
|
|
2527
|
-
}, {
|
|
2528
|
-
name: "proxyPreBuildShared",
|
|
2529
|
-
enforce: "post",
|
|
2530
|
-
config(config, { command }) {
|
|
2531
|
-
setPackageDetectionCwd(config.root || process.cwd());
|
|
2532
|
-
isVinext = hasPackageDependency("vinext");
|
|
2533
|
-
const isRolldown = getIsRolldown(this);
|
|
2534
|
-
_command = command;
|
|
2535
|
-
config.resolve.alias.push(...Object.keys(shared).filter((key) => !(isVinext && key === "react")).map((key) => {
|
|
2536
|
-
const keyBase = key.endsWith("/") ? key.slice(0, -1) : key;
|
|
2537
|
-
const escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2538
|
-
const escapedKeyBase = escapeRegex(keyBase);
|
|
2539
|
-
const pattern = key.endsWith("/") ? `^(${escapedKeyBase}(?:\\/.*)?)$` : `^(${escapedKeyBase})$`;
|
|
2540
|
-
return {
|
|
2541
|
-
find: new RegExp(pattern),
|
|
2542
|
-
replacement: "$1",
|
|
2543
|
-
customResolver(source, importer) {
|
|
2544
|
-
if (/\.css$/.test(source)) return;
|
|
2545
|
-
if (isVinext && source === "react") return;
|
|
2546
|
-
if (importer && importer.includes("localSharedImportMap")) return;
|
|
2547
|
-
if (key.endsWith("/") && source !== key.slice(0, -1)) return;
|
|
2548
|
-
const loadSharePath = getLoadShareModulePath(source, isRolldown, command);
|
|
2549
|
-
writeLoadShareModule(source, shared[key], command, isRolldown);
|
|
2550
|
-
if (shared[key].shareConfig.import !== false) writePreBuildLibPath(source, shared[key]);
|
|
2551
|
-
addUsedShares(source);
|
|
2552
|
-
writeLocalSharedImportMap();
|
|
2553
|
-
return this.resolve(loadSharePath, importer);
|
|
2554
|
-
}
|
|
2555
|
-
};
|
|
2556
|
-
}));
|
|
2557
|
-
config.resolve.alias.push(...Object.keys(shared).filter((key) => !(isVinext && key === "react")).map((key) => {
|
|
2558
|
-
return command === "build" ? {
|
|
2559
|
-
find: new RegExp(`(.*${PREBUILD_TAG}.*)`),
|
|
2560
|
-
replacement: function($1) {
|
|
2561
|
-
const pkgName = assertModuleFound(PREBUILD_TAG, $1).name;
|
|
2562
|
-
return getPrebuildResolutionSource(pkgName, getPreBuildShareItem(pkgName));
|
|
2563
|
-
}
|
|
2564
|
-
} : {
|
|
2565
|
-
find: new RegExp(`(.*${PREBUILD_TAG}.*)`),
|
|
2566
|
-
replacement: "$1",
|
|
2567
|
-
async customResolver(source, importer) {
|
|
2568
|
-
const pkgName = assertModuleFound(PREBUILD_TAG, source).name;
|
|
2569
|
-
const importSource = getPrebuildResolutionSource(pkgName, getPreBuildShareItem(pkgName));
|
|
2570
|
-
const resolved = await this.resolve(importSource, importer);
|
|
2571
|
-
if (!resolved?.id) return;
|
|
2572
|
-
const result = resolved.id;
|
|
2573
|
-
if (_config && !result.includes(_config.cacheDir)) savePrebuild.set(pkgName, Promise.resolve(result));
|
|
2574
|
-
return await this.resolve(await savePrebuild.get(pkgName), importer);
|
|
2575
|
-
}
|
|
2576
|
-
};
|
|
2577
|
-
}));
|
|
2578
|
-
},
|
|
2579
|
-
configResolved(config) {
|
|
2580
|
-
_config = config;
|
|
2581
|
-
const isRolldown = getIsRolldown(this);
|
|
2582
|
-
Object.keys(shared).forEach((key) => {
|
|
2583
|
-
if (key.endsWith("/")) return;
|
|
2584
|
-
if (isVinext && key === "react") {
|
|
2585
|
-
addUsedShares(key);
|
|
2586
|
-
return;
|
|
2587
|
-
}
|
|
2588
|
-
writeLoadShareModule(key, shared[key], _command, isRolldown);
|
|
2589
|
-
if (shared[key].shareConfig.import !== false) writePreBuildLibPath(key, shared[key]);
|
|
2590
|
-
addUsedShares(key);
|
|
2591
|
-
});
|
|
2592
|
-
writeLocalSharedImportMap();
|
|
2593
|
-
}
|
|
2594
|
-
}];
|
|
2595
|
-
}
|
|
2596
|
-
//#endregion
|
|
2597
2772
|
//#region src/plugins/pluginVarRemoteEntry.ts
|
|
2598
2773
|
const VarRemoteEntry = () => {
|
|
2599
2774
|
const mfOptions = getNormalizeModuleFederationOptions();
|
|
@@ -2760,6 +2935,7 @@ var normalizeOptimizeDeps_default = {
|
|
|
2760
2935
|
};
|
|
2761
2936
|
//#endregion
|
|
2762
2937
|
//#region src/index.ts
|
|
2938
|
+
const patchedManualChunks = /* @__PURE__ */ new WeakSet();
|
|
2763
2939
|
const UNSAFE_JS_SOURCE_CHAR_MAP = {
|
|
2764
2940
|
"<": "\\u003C",
|
|
2765
2941
|
">": "\\u003E",
|
|
@@ -2804,6 +2980,10 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
2804
2980
|
config.optimizeDeps = config.optimizeDeps || {};
|
|
2805
2981
|
config.optimizeDeps.include = config.optimizeDeps.include || [];
|
|
2806
2982
|
config.optimizeDeps.include.push(virtualRuntimeInitStatus.getImportId());
|
|
2983
|
+
if (isRolldown) {
|
|
2984
|
+
config.optimizeDeps.exclude = config.optimizeDeps.exclude || [];
|
|
2985
|
+
config.optimizeDeps.exclude.push(...Object.keys(remotes || {}));
|
|
2986
|
+
}
|
|
2807
2987
|
}
|
|
2808
2988
|
for (const key of Object.keys(shared)) {
|
|
2809
2989
|
if (key.endsWith("/")) continue;
|
|
@@ -2834,6 +3014,7 @@ function federation(mfUserOptions) {
|
|
|
2834
3014
|
const remoteEntryId = getRemoteEntryId(options);
|
|
2835
3015
|
const virtualExposesId = getVirtualExposesId(options);
|
|
2836
3016
|
let command;
|
|
3017
|
+
let depsDir = "/node_modules/.vite/deps/";
|
|
2837
3018
|
return [
|
|
2838
3019
|
createEarlyVirtualModulesPlugin(options),
|
|
2839
3020
|
...isVinext ? [{
|
|
@@ -2861,6 +3042,11 @@ function federation(mfUserOptions) {
|
|
|
2861
3042
|
},
|
|
2862
3043
|
configResolved(config) {
|
|
2863
3044
|
VirtualModule.setRoot(config.root);
|
|
3045
|
+
const cacheDir = config.cacheDir;
|
|
3046
|
+
if (cacheDir) {
|
|
3047
|
+
const resolved = path.isAbsolute(cacheDir) ? cacheDir : path.resolve(config.root, cacheDir);
|
|
3048
|
+
depsDir = normalizePath(path.join(resolved, "deps")) + "/";
|
|
3049
|
+
} else depsDir = normalizePath(path.join(config.root, "node_modules", ".vite", "deps")) + "/";
|
|
2864
3050
|
VirtualModule.ensureVirtualPackageExists();
|
|
2865
3051
|
initVirtualModules(command, remoteEntryId);
|
|
2866
3052
|
}
|
|
@@ -2928,17 +3114,20 @@ function federation(mfUserOptions) {
|
|
|
2928
3114
|
let warnedAboutManualChunks = false;
|
|
2929
3115
|
const applyManualChunks = (output) => {
|
|
2930
3116
|
ensureCodeSplitting(output);
|
|
2931
|
-
|
|
3117
|
+
const isPatchedByPlugin = !!(output.manualChunks && patchedManualChunks.has(output.manualChunks));
|
|
3118
|
+
if (output.manualChunks && !isPatchedByPlugin && !warnedAboutManualChunks) {
|
|
2932
3119
|
warnedAboutManualChunks = true;
|
|
2933
3120
|
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.");
|
|
2934
3121
|
}
|
|
2935
|
-
|
|
3122
|
+
const mfManualChunks = function(id) {
|
|
2936
3123
|
if (id.includes(runtimeInitId)) return "runtimeInit";
|
|
2937
3124
|
if (id.includes("__loadShare__")) {
|
|
2938
3125
|
const match = id.match(/([^/\\]+__loadShare__[^/\\]+)/);
|
|
2939
3126
|
return match ? match[1] : "loadShare";
|
|
2940
3127
|
}
|
|
2941
3128
|
};
|
|
3129
|
+
patchedManualChunks.add(mfManualChunks);
|
|
3130
|
+
output.manualChunks = mfManualChunks;
|
|
2942
3131
|
};
|
|
2943
3132
|
config.build.rollupOptions = config.build.rollupOptions || {};
|
|
2944
3133
|
if (!Array.isArray(config.build.rollupOptions.output)) applyManualChunks(config.build.rollupOptions.output ||= {});
|
|
@@ -3122,7 +3311,7 @@ function federation(mfUserOptions) {
|
|
|
3122
3311
|
apply: "serve",
|
|
3123
3312
|
enforce: "post",
|
|
3124
3313
|
transform(code, id) {
|
|
3125
|
-
if (!id.
|
|
3314
|
+
if (!normalizePath(id).split("?")[0].startsWith(depsDir)) return;
|
|
3126
3315
|
const initPattern = /\b(init_\w+__loadShare__\w+)\b/g;
|
|
3127
3316
|
const initFns = /* @__PURE__ */ new Set();
|
|
3128
3317
|
let match;
|
|
@@ -3175,37 +3364,55 @@ function federation(mfUserOptions) {
|
|
|
3175
3364
|
config.optimizeDeps.needsInterop.push(virtualDir);
|
|
3176
3365
|
config.optimizeDeps.needsInterop.push(getLocalSharedImportMapPath());
|
|
3177
3366
|
}
|
|
3367
|
+
const isAstro = hasPackageDependency("astro");
|
|
3178
3368
|
const resolvedTarget = options.target ?? (config.build?.ssr ? "node" : "web");
|
|
3369
|
+
const envTargetDefineValue = !options.target && isAstro ? "undefined" : JSON.stringify(resolvedTarget);
|
|
3179
3370
|
if (!config.define) config.define = {};
|
|
3180
|
-
if (!("ENV_TARGET" in config.define)) config.define["ENV_TARGET"] =
|
|
3371
|
+
if (!("ENV_TARGET" in config.define)) config.define["ENV_TARGET"] = envTargetDefineValue;
|
|
3181
3372
|
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.`);
|
|
3182
3373
|
}
|
|
3183
3374
|
},
|
|
3184
3375
|
...Manifest(),
|
|
3185
3376
|
...VarRemoteEntry(),
|
|
3186
|
-
...
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
const
|
|
3195
|
-
const
|
|
3196
|
-
const
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3377
|
+
...(function() {
|
|
3378
|
+
let disablePreload = false;
|
|
3379
|
+
return Object.keys(options.exposes).length > 0 ? [{
|
|
3380
|
+
name: "module-federation-fix-preload",
|
|
3381
|
+
enforce: "post",
|
|
3382
|
+
apply: "build",
|
|
3383
|
+
config(_config, { command }) {
|
|
3384
|
+
const manifest = options.manifest;
|
|
3385
|
+
const isConsumerProject = Object.keys(options.exposes).length === 0;
|
|
3386
|
+
const getDefaultDisableAssetsAnalyze = (cfgCommand) => cfgCommand === "serve" && isConsumerProject && (typeof manifest !== "object" || !Object.prototype.hasOwnProperty.call(manifest, "disableAssetsAnalyze"));
|
|
3387
|
+
const getConfiguredDisableAssetsAnalyze = (cfgCommand) => {
|
|
3388
|
+
if (typeof manifest === "object" && manifest !== null) {
|
|
3389
|
+
if (Object.prototype.hasOwnProperty.call(manifest, "disableAssetsAnalyze")) return manifest.disableAssetsAnalyze === true;
|
|
3390
|
+
}
|
|
3391
|
+
return getDefaultDisableAssetsAnalyze(cfgCommand);
|
|
3392
|
+
};
|
|
3393
|
+
disablePreload = getConfiguredDisableAssetsAnalyze(command);
|
|
3394
|
+
},
|
|
3395
|
+
generateBundle(_, bundle) {
|
|
3396
|
+
if (disablePreload) return;
|
|
3397
|
+
for (const chunk of Object.values(bundle)) {
|
|
3398
|
+
if (chunk.type !== "chunk") continue;
|
|
3399
|
+
if (!chunk.code.includes("modulepreload")) continue;
|
|
3400
|
+
const chunkDir = path.dirname(chunk.fileName);
|
|
3401
|
+
const prefixToRoot = chunkDir === "." ? "" : `${path.relative(chunkDir, ".")}/`;
|
|
3402
|
+
const replacementExpr = prefixToRoot ? `${escapeUnsafeJsSourceChars(JSON.stringify(prefixToRoot))}+$1` : "$1";
|
|
3403
|
+
const replacement = `=function($1){return new URL(${replacementExpr},import.meta.url).href}`;
|
|
3404
|
+
const replaced = chunk.code.replace(/=\(?(\w+)(?:,\w+)?\)?\s*=>\s*["'`][^"'`]*["'`]\s*\+\s*\1/, replacement);
|
|
3405
|
+
if (replaced !== chunk.code) {
|
|
3406
|
+
chunk.code = replaced;
|
|
3407
|
+
continue;
|
|
3408
|
+
}
|
|
3409
|
+
chunk.code = chunk.code.replace(/=function\((\w+)(?:,\w+)?\)\{return\s*["'`][^"'`]*["'`]\s*\+\s*\1\s*\}/, replacement);
|
|
3410
|
+
chunk.code = chunk.code.replace(/=function\((\w+)(?:,\w+)?\)\{return new URL\("\.\.\/"\+\1,import\.meta\.url\)\.href\}/, replacement);
|
|
3411
|
+
chunk.code = chunk.code.replace(/new URL\("\.\.\/"\+(\w+),import\.meta\.url\)\.href/g, `new URL(${replacementExpr},import.meta.url).href`);
|
|
3202
3412
|
}
|
|
3203
|
-
chunk.code = chunk.code.replace(/=function\((\w+)(?:,\w+)?\)\{return\s*["'`][^"'`]*["'`]\s*\+\s*\1\s*\}/, replacement);
|
|
3204
|
-
chunk.code = chunk.code.replace(/=function\((\w+)(?:,\w+)?\)\{return new URL\("\.\.\/"\+\1,import\.meta\.url\)\.href\}/, replacement);
|
|
3205
|
-
chunk.code = chunk.code.replace(/new URL\("\.\.\/"\+(\w+),import\.meta\.url\)\.href/g, `new URL(${replacementExpr},import.meta.url).href`);
|
|
3206
3413
|
}
|
|
3207
|
-
}
|
|
3208
|
-
}
|
|
3414
|
+
}] : [];
|
|
3415
|
+
})()
|
|
3209
3416
|
];
|
|
3210
3417
|
}
|
|
3211
3418
|
//#endregion
|