Project Init

This commit is contained in:
Muluhabt
2026-05-29 15:23:46 +03:00
commit 2fbc557aac
67387 changed files with 6063341 additions and 0 deletions

View File

@@ -0,0 +1,31 @@
//#region \0rolldown/runtime.js
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
key = keys[i];
if (!__hasOwnProp.call(to, key) && key !== except) {
__defProp(to, key, {
get: ((k) => from[k]).bind(null, key),
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
}
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
value: mod,
enumerable: true
}) : target, mod));
//#endregion
exports.__commonJSMin = __commonJSMin;
exports.__toESM = __toESM;

View File

@@ -0,0 +1,8 @@
import { createRequire } from "node:module";
//#region \0rolldown/runtime.js
var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
var __require = /* @__PURE__ */ createRequire(import.meta.url);
//#endregion
export { __commonJSMin, __require };

View File

@@ -0,0 +1,308 @@
const require_runtime = require('../_virtual/_rolldown/runtime.js');
//#region src/plugins/ChunkCorrelationPlugin.js
var require_ChunkCorrelationPlugin = /* @__PURE__ */ require_runtime.__commonJSMin(((exports, module) => {
const PLUGIN_NAME = "FederationStatsPlugin";
/** @typedef {import("./webpack-stats-types").WebpackStats} WebpackStats */
/** @typedef {import( "./webpack-stats-types").WebpackStatsChunk} WebpackStatsChunk */
/** @typedef {import("./webpack-stats-types").WebpackStatsModule} WebpackStatsModule */
/**
* @typedef {object} SharedDependency
* @property {string} shareScope
* @property {string} shareKey
* @property {string} requiredVersion
* @property {boolean} strictVersion
* @property {boolean} singleton
* @property {boolean} eager
*/
/**
* @typedef {object} SharedModule
* @property {string[]} chunks
* @property {SharedDependency[]} provides
*/
/**
* @typedef {object} Exposed
* @property {string[]} chunks
* @property {SharedModule[]} sharedModules
*/
/**
* @typedef {object} FederatedContainer
* @property {string} remote
* @property {string} entry
* @property {SharedModule[]} sharedModules
* @property {{ [key: string]: Exposed }} exposes
*/
/**
* @typedef {object} FederatedStats
* @property {SharedModule[]} sharedModules
* @property {FederatedContainer[]} federatedModules
*/
const concat = (x, y) => x.concat(y);
const flatMap = (xs, f) => xs.map(f).reduce(concat, []);
/**
*
* @param {WebpackStats} stats
* @returns {}
*/
function getRemoteModules(stats) {
return stats.modules.filter((mod) => mod.moduleType === "remote-module").reduce((acc, remoteModule) => {
acc[remoteModule.nameForCondition] = remoteModule.id;
return acc;
}, {});
}
/**
*
* @param {WebpackStats} stats
* @param {string} exposedFile
* @returns {WebpackStatsModule[]}
*/
function getExposedModules(stats, exposedFile) {
return stats.modules.filter((mod) => mod.name?.startsWith(exposedFile));
}
/**
*
* @param {WebpackStats} stats
* @param {WebpackStatsModule} mod
* @returns {Exposed}
*/
function getExposed(stats, mod) {
const chunks = stats.chunks.filter((chunk) => {
return chunk.modules.find((modsInChunk) => {
return modsInChunk.id === mod.id && !modsInChunk.dependent;
});
});
const dependencies = stats.modules.filter((sharedModule) => {
if (sharedModule.moduleType !== "consume-shared-module") return false;
return sharedModule.issuerId === mod.id;
}).map((sharedModule) => {
return sharedModule.identifier.split("|")[2];
});
return flatMap(chunks, (chunk) => ({ [chunk.id]: {
files: chunk.files.map((f) => `${stats.publicPath === "auto" ? "" : stats.publicPath || ""}${f}`),
requiredModules: dependencies
} })).reduce((acc, chunk) => {
Object.assign(acc, chunk);
return acc;
}, {});
}
/**
*
* @param {import("webpack").Module} mod
* @param {(issuer: string) => boolean} check
* @returns {boolean}
*/
function searchIssuer(mod, check) {
if (mod.issuer && check(mod.issuer)) return true;
return !!mod.modules && mod.modules.some((m) => searchIssuer(m, check));
}
function searchReason(mod, check) {
if (mod.reasons && check(mod.reasons)) return true;
return !!mod.reasons && mod.reasons.some((m) => searchReason(m, check));
}
function searchIssuerAndReason(mod, check) {
const foundIssuer = searchIssuer(mod, (issuer) => check(issuer));
if (foundIssuer) return foundIssuer;
return searchReason(mod, (reason) => reason.some((r) => check(r?.moduleIdentifier)));
}
/**
* @param {import("webpack").Module} mod
* @param {(issuer: string) => boolean} check
* @returns {string[]}
*/
function getIssuers(mod, check) {
if (mod.issuer && check(mod.issuer)) return [mod.issuer];
return mod.modules && mod.modules.filter((m) => searchIssuer(m, check)).map((m) => m.issuer) || [];
}
function getIssuersAndReasons(mod, check) {
if (mod.issuer && check(mod.issuer)) return [mod.issuer];
if (mod.reasons && searchReason(mod, (reason) => reason.some((r) => check(r?.moduleIdentifier)))) return mod.reasons.filter((r) => {
return r.moduleIdentifier && check(r.moduleIdentifier);
}).map((r) => r.moduleIdentifier);
return mod.modules && mod.modules.filter((m) => searchIssuerAndReason(m, check)).map((m) => {
return m.issuer || m.reasons.find((r) => check(r?.moduleIdentifier)).moduleIdentifier;
}) || [];
}
/**
* @param {string} issuer
* @returns {SharedDependency}
*/
function parseFederatedIssuer(issuer) {
const split = issuer?.split("|") || [];
if (split.length !== 8 || split[0] !== "consume-shared-module") return null;
const [, shareScope, shareKey, requiredVersion, strictVersion, , singleton, eager] = split;
return {
shareScope,
shareKey,
requiredVersion,
strictVersion: JSON.parse(strictVersion),
singleton: JSON.parse(singleton),
eager: JSON.parse(eager)
};
}
/**
*
* @param {WebpackStats} stats
* @param {import("webpack").container.ModuleFederationPlugin} federationPlugin
* @returns {SharedModule[]}
*/
function getSharedModules(stats, federationPlugin) {
return flatMap(stats.chunks.filter((chunk) => {
if (!stats.entrypoints[federationPlugin.name]) return false;
return stats.entrypoints[federationPlugin.name].chunks.some((id) => chunk.id === id);
}), (chunk) => flatMap(chunk.children, (id) => stats.chunks.filter((c) => c.id === id && c.files.length > 0 && c.parents.some((p) => stats.entrypoints[federationPlugin.name].chunks.some((c) => c === p)) && c.modules.some((m) => searchIssuer(m, (issuer) => issuer?.startsWith("consume-shared-module")))))).map((chunk) => ({
chunks: chunk.files.map((f) => `${stats.publicPath === "auto" ? "" : stats.publicPath || ""}${f}`),
provides: flatMap(chunk.modules.filter((m) => searchIssuer(m, (issuer) => issuer?.startsWith("consume-shared-module"))), (m) => getIssuers(m, (issuer) => issuer?.startsWith("consume-shared-module"))).map(parseFederatedIssuer).filter((f) => !!f)
})).filter((c) => c.provides.length > 0);
}
/**
* @param {WebpackStats} stats
* @returns {SharedModule[]}
*/
function getMainSharedModules(stats) {
return flatMap(stats.namedChunkGroups["main"] ? flatMap(stats.namedChunkGroups["main"].chunks, (c) => stats.chunks.filter((chunk) => chunk.id === c)) : [], (chunk) => flatMap(chunk.children, (id) => stats.chunks.filter((c) => {
return c.id === id && c.files.length > 0 && c.modules.some((m) => {
return searchIssuerAndReason(m, (check) => check?.startsWith("consume-shared-module"));
});
}))).map((chunk) => {
return {
chunks: chunk.files.map((f) => `${stats.publicPath === "auto" ? "" : stats.publicPath || ""}${f}`),
provides: flatMap(chunk.modules.filter((m) => searchIssuerAndReason(m, (check) => check?.startsWith("consume-shared-module"))), (m) => getIssuersAndReasons(m, (issuer) => issuer?.startsWith("consume-shared-module"))).map(parseFederatedIssuer).filter((f) => !!f)
};
}).filter((c) => c.provides.length > 0);
}
/**
*
* @param {WebpackStats} stats
* @param {import("webpack").container.ModuleFederationPlugin} federationPlugin
* @returns {FederatedStats}
*/
function getFederationStats(stats, federationPluginOptions) {
const exposedModules = Object.entries(federationPluginOptions.exposes).reduce((exposedModules, [exposedAs, exposedFile]) => Object.assign(exposedModules, { [exposedAs]: getExposedModules(stats, exposedFile) }), {});
/** @type {{ [key: string]: Exposed }} */
const exposes = Object.entries(exposedModules).reduce((exposedChunks, [exposedAs, exposedModules]) => Object.assign(exposedChunks, { [exposedAs]: flatMap(exposedModules, (mod) => getExposed(stats, mod)) }), {});
/** @type {string} */
const remote = federationPluginOptions.library?.name || federationPluginOptions.name;
const sharedModules = getSharedModules(stats, federationPluginOptions);
const remoteModules = getRemoteModules(stats);
return {
remote,
entry: `${stats.publicPath === "auto" ? "" : stats.publicPath || ""}${stats.assetsByChunkName[remote] && stats.assetsByChunkName[remote].length === 1 ? stats.assetsByChunkName[remote][0] : federationPluginOptions.filename}`,
sharedModules,
exposes,
remoteModules
};
}
/**
* @typedef {object} FederationStatsPluginOptions
* @property {string | string[]} filename The filename or an array of filenames in the `output.path` directory to write stats to.
*/
/**
* Writes relevant federation stats to a file for further consumption.
*/
var FederationStatsPlugin = class {
/**
*
* @param {FederationStatsPluginOptions} options
*/
constructor(options) {
if (!options || !options.filename) throw new Error("filename option is required.");
this._options = options;
}
/**
*
* @param {import("webpack").Compiler} compiler
*/
apply(compiler) {
const federationPlugins = compiler.options.plugins?.filter((plugin) => [
"NextFederationPlugin",
"UniversalFederationPlugin",
"NodeFederationPlugin",
"ModuleFederationPlugin"
].includes(plugin.constructor.name) && plugin?._options?.exposes);
if (!federationPlugins || federationPlugins.length === 0) return;
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
compilation.hooks.processAssets.tap({
name: PLUGIN_NAME,
stage: compilation.constructor.PROCESS_ASSETS_STAGE_REPORT
}, () => {
const [federationOpts] = federationPlugins.map((federationPlugin) => federationPlugin?._options);
let container;
for (const [name, entry] of compilation.entrypoints) {
if (container) break;
federationOpts.name.includes(name) && (container = entry);
}
if (!container) return;
container = container?.getEntrypointChunk();
const [containerEntryModule] = Array.from(compilation.chunkGraph.getChunkEntryModulesIterable(container));
const { blocks } = containerEntryModule;
const exposedResolved = {};
const builtExposes = {};
for (let block of blocks) {
const blockmodule = block;
for (const dep of blockmodule.dependencies) {
const connection = compilation.moduleGraph.getConnection(dep);
if (!connection) continue;
const { module: module$1 } = connection;
const moduleChunks = compilation.chunkGraph.getModuleChunksIterable(module$1);
for (let exposedChunk of moduleChunks) {
const isForThisRuntime = (typeof exposedChunk.runtime === "string" ? new Set([exposedChunk.runtime]) : exposedChunk.runtime).has(containerEntryModule._name);
const moduleActuallyNeedsChunk = compilation.chunkGraph.getChunkRootModules(exposedChunk).includes(module$1);
if (!isForThisRuntime || !moduleActuallyNeedsChunk) continue;
builtExposes[dep.exposedName] = [...builtExposes[dep.exposedName] || [], ...exposedChunk.files || []];
}
exposedResolved[dep.exposedName] = module$1;
}
}
const stats = compilation.getStats().toJson({
all: false,
assets: true,
reasons: true,
modules: true,
children: true,
chunkGroups: true,
chunkModules: true,
chunkOrigins: false,
entrypoints: true,
namedChunkGroups: false,
chunkRelations: true,
chunks: true,
ids: true,
nestedModules: false,
outputPath: true,
publicPath: true
});
const federatedModules = getFederationStats(stats, federationOpts);
federatedModules.exposes = builtExposes;
const sharedModules = getMainSharedModules(stats);
const vendorChunks = /* @__PURE__ */ new Set();
for (const share of sharedModules) if (share?.chunks) for (const file of share.chunks) vendorChunks.add(file);
const statsResult = {
sharedModules,
federatedModules: [federatedModules]
};
const statsJson = JSON.stringify(statsResult);
const statsBuffer = Buffer.from(statsJson, "utf-8");
const statsSource = {
source: () => statsBuffer,
size: () => statsBuffer.length
};
const { filename } = this._options;
if (Array.isArray(filename)) for (const file of filename) if (compilation.getAsset(file)) compilation.updateAsset(file, statsSource);
else compilation.emitAsset(file, statsSource);
else if (compilation.getAsset(filename)) compilation.updateAsset(filename, statsSource);
else compilation.emitAsset(filename, statsSource);
});
});
}
};
module.exports = FederationStatsPlugin;
}));
//#endregion
Object.defineProperty(exports, 'default', {
enumerable: true,
get: function () {
return require_ChunkCorrelationPlugin();
}
});
//# sourceMappingURL=ChunkCorrelationPlugin.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,305 @@
import { __commonJSMin } from "../_virtual/_rolldown/runtime.mjs";
//#region src/plugins/ChunkCorrelationPlugin.js
var require_ChunkCorrelationPlugin = /* @__PURE__ */ __commonJSMin(((exports, module) => {
const PLUGIN_NAME = "FederationStatsPlugin";
/** @typedef {import("./webpack-stats-types").WebpackStats} WebpackStats */
/** @typedef {import( "./webpack-stats-types").WebpackStatsChunk} WebpackStatsChunk */
/** @typedef {import("./webpack-stats-types").WebpackStatsModule} WebpackStatsModule */
/**
* @typedef {object} SharedDependency
* @property {string} shareScope
* @property {string} shareKey
* @property {string} requiredVersion
* @property {boolean} strictVersion
* @property {boolean} singleton
* @property {boolean} eager
*/
/**
* @typedef {object} SharedModule
* @property {string[]} chunks
* @property {SharedDependency[]} provides
*/
/**
* @typedef {object} Exposed
* @property {string[]} chunks
* @property {SharedModule[]} sharedModules
*/
/**
* @typedef {object} FederatedContainer
* @property {string} remote
* @property {string} entry
* @property {SharedModule[]} sharedModules
* @property {{ [key: string]: Exposed }} exposes
*/
/**
* @typedef {object} FederatedStats
* @property {SharedModule[]} sharedModules
* @property {FederatedContainer[]} federatedModules
*/
const concat = (x, y) => x.concat(y);
const flatMap = (xs, f) => xs.map(f).reduce(concat, []);
/**
*
* @param {WebpackStats} stats
* @returns {}
*/
function getRemoteModules(stats) {
return stats.modules.filter((mod) => mod.moduleType === "remote-module").reduce((acc, remoteModule) => {
acc[remoteModule.nameForCondition] = remoteModule.id;
return acc;
}, {});
}
/**
*
* @param {WebpackStats} stats
* @param {string} exposedFile
* @returns {WebpackStatsModule[]}
*/
function getExposedModules(stats, exposedFile) {
return stats.modules.filter((mod) => mod.name?.startsWith(exposedFile));
}
/**
*
* @param {WebpackStats} stats
* @param {WebpackStatsModule} mod
* @returns {Exposed}
*/
function getExposed(stats, mod) {
const chunks = stats.chunks.filter((chunk) => {
return chunk.modules.find((modsInChunk) => {
return modsInChunk.id === mod.id && !modsInChunk.dependent;
});
});
const dependencies = stats.modules.filter((sharedModule) => {
if (sharedModule.moduleType !== "consume-shared-module") return false;
return sharedModule.issuerId === mod.id;
}).map((sharedModule) => {
return sharedModule.identifier.split("|")[2];
});
return flatMap(chunks, (chunk) => ({ [chunk.id]: {
files: chunk.files.map((f) => `${stats.publicPath === "auto" ? "" : stats.publicPath || ""}${f}`),
requiredModules: dependencies
} })).reduce((acc, chunk) => {
Object.assign(acc, chunk);
return acc;
}, {});
}
/**
*
* @param {import("webpack").Module} mod
* @param {(issuer: string) => boolean} check
* @returns {boolean}
*/
function searchIssuer(mod, check) {
if (mod.issuer && check(mod.issuer)) return true;
return !!mod.modules && mod.modules.some((m) => searchIssuer(m, check));
}
function searchReason(mod, check) {
if (mod.reasons && check(mod.reasons)) return true;
return !!mod.reasons && mod.reasons.some((m) => searchReason(m, check));
}
function searchIssuerAndReason(mod, check) {
const foundIssuer = searchIssuer(mod, (issuer) => check(issuer));
if (foundIssuer) return foundIssuer;
return searchReason(mod, (reason) => reason.some((r) => check(r?.moduleIdentifier)));
}
/**
* @param {import("webpack").Module} mod
* @param {(issuer: string) => boolean} check
* @returns {string[]}
*/
function getIssuers(mod, check) {
if (mod.issuer && check(mod.issuer)) return [mod.issuer];
return mod.modules && mod.modules.filter((m) => searchIssuer(m, check)).map((m) => m.issuer) || [];
}
function getIssuersAndReasons(mod, check) {
if (mod.issuer && check(mod.issuer)) return [mod.issuer];
if (mod.reasons && searchReason(mod, (reason) => reason.some((r) => check(r?.moduleIdentifier)))) return mod.reasons.filter((r) => {
return r.moduleIdentifier && check(r.moduleIdentifier);
}).map((r) => r.moduleIdentifier);
return mod.modules && mod.modules.filter((m) => searchIssuerAndReason(m, check)).map((m) => {
return m.issuer || m.reasons.find((r) => check(r?.moduleIdentifier)).moduleIdentifier;
}) || [];
}
/**
* @param {string} issuer
* @returns {SharedDependency}
*/
function parseFederatedIssuer(issuer) {
const split = issuer?.split("|") || [];
if (split.length !== 8 || split[0] !== "consume-shared-module") return null;
const [, shareScope, shareKey, requiredVersion, strictVersion, , singleton, eager] = split;
return {
shareScope,
shareKey,
requiredVersion,
strictVersion: JSON.parse(strictVersion),
singleton: JSON.parse(singleton),
eager: JSON.parse(eager)
};
}
/**
*
* @param {WebpackStats} stats
* @param {import("webpack").container.ModuleFederationPlugin} federationPlugin
* @returns {SharedModule[]}
*/
function getSharedModules(stats, federationPlugin) {
return flatMap(stats.chunks.filter((chunk) => {
if (!stats.entrypoints[federationPlugin.name]) return false;
return stats.entrypoints[federationPlugin.name].chunks.some((id) => chunk.id === id);
}), (chunk) => flatMap(chunk.children, (id) => stats.chunks.filter((c) => c.id === id && c.files.length > 0 && c.parents.some((p) => stats.entrypoints[federationPlugin.name].chunks.some((c) => c === p)) && c.modules.some((m) => searchIssuer(m, (issuer) => issuer?.startsWith("consume-shared-module")))))).map((chunk) => ({
chunks: chunk.files.map((f) => `${stats.publicPath === "auto" ? "" : stats.publicPath || ""}${f}`),
provides: flatMap(chunk.modules.filter((m) => searchIssuer(m, (issuer) => issuer?.startsWith("consume-shared-module"))), (m) => getIssuers(m, (issuer) => issuer?.startsWith("consume-shared-module"))).map(parseFederatedIssuer).filter((f) => !!f)
})).filter((c) => c.provides.length > 0);
}
/**
* @param {WebpackStats} stats
* @returns {SharedModule[]}
*/
function getMainSharedModules(stats) {
return flatMap(stats.namedChunkGroups["main"] ? flatMap(stats.namedChunkGroups["main"].chunks, (c) => stats.chunks.filter((chunk) => chunk.id === c)) : [], (chunk) => flatMap(chunk.children, (id) => stats.chunks.filter((c) => {
return c.id === id && c.files.length > 0 && c.modules.some((m) => {
return searchIssuerAndReason(m, (check) => check?.startsWith("consume-shared-module"));
});
}))).map((chunk) => {
return {
chunks: chunk.files.map((f) => `${stats.publicPath === "auto" ? "" : stats.publicPath || ""}${f}`),
provides: flatMap(chunk.modules.filter((m) => searchIssuerAndReason(m, (check) => check?.startsWith("consume-shared-module"))), (m) => getIssuersAndReasons(m, (issuer) => issuer?.startsWith("consume-shared-module"))).map(parseFederatedIssuer).filter((f) => !!f)
};
}).filter((c) => c.provides.length > 0);
}
/**
*
* @param {WebpackStats} stats
* @param {import("webpack").container.ModuleFederationPlugin} federationPlugin
* @returns {FederatedStats}
*/
function getFederationStats(stats, federationPluginOptions) {
const exposedModules = Object.entries(federationPluginOptions.exposes).reduce((exposedModules, [exposedAs, exposedFile]) => Object.assign(exposedModules, { [exposedAs]: getExposedModules(stats, exposedFile) }), {});
/** @type {{ [key: string]: Exposed }} */
const exposes = Object.entries(exposedModules).reduce((exposedChunks, [exposedAs, exposedModules]) => Object.assign(exposedChunks, { [exposedAs]: flatMap(exposedModules, (mod) => getExposed(stats, mod)) }), {});
/** @type {string} */
const remote = federationPluginOptions.library?.name || federationPluginOptions.name;
const sharedModules = getSharedModules(stats, federationPluginOptions);
const remoteModules = getRemoteModules(stats);
return {
remote,
entry: `${stats.publicPath === "auto" ? "" : stats.publicPath || ""}${stats.assetsByChunkName[remote] && stats.assetsByChunkName[remote].length === 1 ? stats.assetsByChunkName[remote][0] : federationPluginOptions.filename}`,
sharedModules,
exposes,
remoteModules
};
}
/**
* @typedef {object} FederationStatsPluginOptions
* @property {string | string[]} filename The filename or an array of filenames in the `output.path` directory to write stats to.
*/
/**
* Writes relevant federation stats to a file for further consumption.
*/
var FederationStatsPlugin = class {
/**
*
* @param {FederationStatsPluginOptions} options
*/
constructor(options) {
if (!options || !options.filename) throw new Error("filename option is required.");
this._options = options;
}
/**
*
* @param {import("webpack").Compiler} compiler
*/
apply(compiler) {
const federationPlugins = compiler.options.plugins?.filter((plugin) => [
"NextFederationPlugin",
"UniversalFederationPlugin",
"NodeFederationPlugin",
"ModuleFederationPlugin"
].includes(plugin.constructor.name) && plugin?._options?.exposes);
if (!federationPlugins || federationPlugins.length === 0) return;
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
compilation.hooks.processAssets.tap({
name: PLUGIN_NAME,
stage: compilation.constructor.PROCESS_ASSETS_STAGE_REPORT
}, () => {
const [federationOpts] = federationPlugins.map((federationPlugin) => federationPlugin?._options);
let container;
for (const [name, entry] of compilation.entrypoints) {
if (container) break;
federationOpts.name.includes(name) && (container = entry);
}
if (!container) return;
container = container?.getEntrypointChunk();
const [containerEntryModule] = Array.from(compilation.chunkGraph.getChunkEntryModulesIterable(container));
const { blocks } = containerEntryModule;
const exposedResolved = {};
const builtExposes = {};
for (let block of blocks) {
const blockmodule = block;
for (const dep of blockmodule.dependencies) {
const connection = compilation.moduleGraph.getConnection(dep);
if (!connection) continue;
const { module: module$1 } = connection;
const moduleChunks = compilation.chunkGraph.getModuleChunksIterable(module$1);
for (let exposedChunk of moduleChunks) {
const isForThisRuntime = (typeof exposedChunk.runtime === "string" ? new Set([exposedChunk.runtime]) : exposedChunk.runtime).has(containerEntryModule._name);
const moduleActuallyNeedsChunk = compilation.chunkGraph.getChunkRootModules(exposedChunk).includes(module$1);
if (!isForThisRuntime || !moduleActuallyNeedsChunk) continue;
builtExposes[dep.exposedName] = [...builtExposes[dep.exposedName] || [], ...exposedChunk.files || []];
}
exposedResolved[dep.exposedName] = module$1;
}
}
const stats = compilation.getStats().toJson({
all: false,
assets: true,
reasons: true,
modules: true,
children: true,
chunkGroups: true,
chunkModules: true,
chunkOrigins: false,
entrypoints: true,
namedChunkGroups: false,
chunkRelations: true,
chunks: true,
ids: true,
nestedModules: false,
outputPath: true,
publicPath: true
});
const federatedModules = getFederationStats(stats, federationOpts);
federatedModules.exposes = builtExposes;
const sharedModules = getMainSharedModules(stats);
const vendorChunks = /* @__PURE__ */ new Set();
for (const share of sharedModules) if (share?.chunks) for (const file of share.chunks) vendorChunks.add(file);
const statsResult = {
sharedModules,
federatedModules: [federatedModules]
};
const statsJson = JSON.stringify(statsResult);
const statsBuffer = Buffer.from(statsJson, "utf-8");
const statsSource = {
source: () => statsBuffer,
size: () => statsBuffer.length
};
const { filename } = this._options;
if (Array.isArray(filename)) for (const file of filename) if (compilation.getAsset(file)) compilation.updateAsset(file, statsSource);
else compilation.emitAsset(file, statsSource);
else if (compilation.getAsset(filename)) compilation.updateAsset(filename, statsSource);
else compilation.emitAsset(filename, statsSource);
});
});
}
};
module.exports = FederationStatsPlugin;
}));
//#endregion
export default require_ChunkCorrelationPlugin();
export { require_ChunkCorrelationPlugin };
//# sourceMappingURL=ChunkCorrelationPlugin.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,21 @@
//#region src/filesystem/stratagies.d.ts
declare function fileSystemRunInContextStrategy(chunkId: string, rootOutputDir: string, remotes: Remotes, callback: CallbackFunction): Promise<void>;
declare function httpEvalStrategy(chunkName: string, remoteName: string, remotes: Remotes, callback: CallbackFunction): Promise<void>;
interface Remotes {
[key: string]: {
entry: string;
};
}
type CallbackFunction = (error: Error | null, chunk?: any) => void;
/**
* HttpVmStrategy
* This function is used to execute a chunk of code in a VM using HTTP or HTTPS based on the protocol.
* @param {string} chunkName - The name of the chunk to be executed.
* @param {string} remoteName - The name of the remote server.
* @param {Remotes} remotes - An object containing the remote servers.
* @param {CallbackFunction} callback - A callback function to be executed after the chunk is executed.
*/
declare function httpVmStrategy(chunkName: string, remoteName: string, remotes: Remotes, callback: CallbackFunction): Promise<void>;
//#endregion
export { fileSystemRunInContextStrategy, httpEvalStrategy, httpVmStrategy };
//# sourceMappingURL=stratagies.d.mts.map

View File

@@ -0,0 +1,21 @@
//#region src/filesystem/stratagies.d.ts
declare function fileSystemRunInContextStrategy(chunkId: string, rootOutputDir: string, remotes: Remotes, callback: CallbackFunction): Promise<void>;
declare function httpEvalStrategy(chunkName: string, remoteName: string, remotes: Remotes, callback: CallbackFunction): Promise<void>;
interface Remotes {
[key: string]: {
entry: string;
};
}
type CallbackFunction = (error: Error | null, chunk?: any) => void;
/**
* HttpVmStrategy
* This function is used to execute a chunk of code in a VM using HTTP or HTTPS based on the protocol.
* @param {string} chunkName - The name of the chunk to be executed.
* @param {string} remoteName - The name of the remote server.
* @param {Remotes} remotes - An object containing the remote servers.
* @param {CallbackFunction} callback - A callback function to be executed after the chunk is executed.
*/
declare function httpVmStrategy(chunkName: string, remoteName: string, remotes: Remotes, callback: CallbackFunction): Promise<void>;
//#endregion
export { fileSystemRunInContextStrategy, httpEvalStrategy, httpVmStrategy };
//# sourceMappingURL=stratagies.d.ts.map

View File

@@ -0,0 +1,105 @@
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
//#region src/filesystem/stratagies.ts
async function fileSystemRunInContextStrategy(chunkId, rootOutputDir, remotes, callback) {
const fs = require("fs");
const path = require("path");
const vm = require("vm");
const filename = path.join(__dirname, rootOutputDir + __webpack_require__.u(chunkId));
if (fs.existsSync(filename)) fs.readFile(filename, "utf-8", (err, content) => {
if (err) {
callback(err, null);
return;
}
const chunk = {};
try {
vm.runInThisContext("(function(exports, require, __dirname, __filename) {" + content + "\n})", filename)(chunk, require, path.dirname(filename), filename);
callback(null, chunk);
} catch (e) {
console.log("'runInThisContext threw'", e);
callback(e, null);
}
});
else callback(/* @__PURE__ */ new Error(`File ${filename} does not exist`), null);
}
async function httpEvalStrategy(chunkName, remoteName, remotes, callback) {
let url;
try {
url = new URL(chunkName, __webpack_require__.p);
} catch (e) {
console.error("module-federation: failed to construct absolute chunk path of", remoteName, "for", chunkName);
url = new URL(remotes[remoteName]);
const getBasenameFromUrl = (url) => {
const urlParts = url.split("/");
return urlParts[urlParts.length - 1];
};
const fileToReplace = getBasenameFromUrl(url.pathname);
url.pathname = url.pathname.replace(fileToReplace, chunkName);
}
const data = await fetch(url).then((res) => res.text());
const chunk = {};
try {
const urlDirname = url.pathname.split("/").slice(0, -1).join("/");
eval("(function(exports, require, __dirname, __filename) {" + data + "\n})")(chunk, require, urlDirname, chunkName);
callback(null, chunk);
} catch (e) {
callback(e, null);
}
}
/**
* HttpVmStrategy
* This function is used to execute a chunk of code in a VM using HTTP or HTTPS based on the protocol.
* @param {string} chunkName - The name of the chunk to be executed.
* @param {string} remoteName - The name of the remote server.
* @param {Remotes} remotes - An object containing the remote servers.
* @param {CallbackFunction} callback - A callback function to be executed after the chunk is executed.
*/
async function httpVmStrategy(chunkName, remoteName, remotes, callback) {
const http = require("http");
const https = require("https");
const vm = require("vm");
const path = require("path");
let url;
const globalThisVal = new Function("return globalThis")();
try {
url = new URL(chunkName, __webpack_require__.p);
} catch (e) {
console.error("module-federation: failed to construct absolute chunk path of", remoteName, "for", chunkName);
const container = globalThisVal["__FEDERATION__"]["__INSTANCES__"].find((instance) => {
if (!instance) return;
if (!instance.moduleCache.has(remoteName)) return;
const container = instance.moduleCache.get(remoteName);
if (!container.remoteInfo) return;
return container.remoteInfo.entry;
});
if (!container) throw new Error("Container not found");
url = new URL(container.moduleCache.get(remoteName).remoteInfo.entry);
const fileToReplace = path.basename(url.pathname);
url.pathname = url.pathname.replace(fileToReplace, chunkName);
}
(url.protocol === "https:" ? https : http).get(url.href, (res) => {
let data = "";
res.on("data", (chunk) => {
data += chunk.toString();
});
res.on("end", () => {
const chunk = {};
const urlDirname = url.pathname.split("/").slice(0, -1).join("/");
try {
vm.runInThisContext(`(function(exports, require, __dirname, __filename) {${data}\n})`, chunkName)(chunk, require, urlDirname, chunkName);
callback(null, chunk);
} catch (err) {
callback(err, null);
}
});
res.on("error", (err) => {
callback(err, null);
});
}).on("error", (err) => callback(err, null));
}
//#endregion
exports.fileSystemRunInContextStrategy = fileSystemRunInContextStrategy;
exports.httpEvalStrategy = httpEvalStrategy;
exports.httpVmStrategy = httpVmStrategy;
//# sourceMappingURL=stratagies.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,103 @@
import { __require } from "../../_virtual/_rolldown/runtime.mjs";
//#region src/filesystem/stratagies.ts
async function fileSystemRunInContextStrategy(chunkId, rootOutputDir, remotes, callback) {
const fs = __require("fs");
const path = __require("path");
const vm = __require("vm");
const filename = path.join(__dirname, rootOutputDir + __webpack_require__.u(chunkId));
if (fs.existsSync(filename)) fs.readFile(filename, "utf-8", (err, content) => {
if (err) {
callback(err, null);
return;
}
const chunk = {};
try {
vm.runInThisContext("(function(exports, require, __dirname, __filename) {" + content + "\n})", filename)(chunk, __require, path.dirname(filename), filename);
callback(null, chunk);
} catch (e) {
console.log("'runInThisContext threw'", e);
callback(e, null);
}
});
else callback(/* @__PURE__ */ new Error(`File ${filename} does not exist`), null);
}
async function httpEvalStrategy(chunkName, remoteName, remotes, callback) {
let url;
try {
url = new URL(chunkName, __webpack_require__.p);
} catch (e) {
console.error("module-federation: failed to construct absolute chunk path of", remoteName, "for", chunkName);
url = new URL(remotes[remoteName]);
const getBasenameFromUrl = (url) => {
const urlParts = url.split("/");
return urlParts[urlParts.length - 1];
};
const fileToReplace = getBasenameFromUrl(url.pathname);
url.pathname = url.pathname.replace(fileToReplace, chunkName);
}
const data = await fetch(url).then((res) => res.text());
const chunk = {};
try {
const urlDirname = url.pathname.split("/").slice(0, -1).join("/");
eval("(function(exports, require, __dirname, __filename) {" + data + "\n})")(chunk, __require, urlDirname, chunkName);
callback(null, chunk);
} catch (e) {
callback(e, null);
}
}
/**
* HttpVmStrategy
* This function is used to execute a chunk of code in a VM using HTTP or HTTPS based on the protocol.
* @param {string} chunkName - The name of the chunk to be executed.
* @param {string} remoteName - The name of the remote server.
* @param {Remotes} remotes - An object containing the remote servers.
* @param {CallbackFunction} callback - A callback function to be executed after the chunk is executed.
*/
async function httpVmStrategy(chunkName, remoteName, remotes, callback) {
const http = __require("http");
const https = __require("https");
const vm = __require("vm");
const path = __require("path");
let url;
const globalThisVal = new Function("return globalThis")();
try {
url = new URL(chunkName, __webpack_require__.p);
} catch (e) {
console.error("module-federation: failed to construct absolute chunk path of", remoteName, "for", chunkName);
const container = globalThisVal["__FEDERATION__"]["__INSTANCES__"].find((instance) => {
if (!instance) return;
if (!instance.moduleCache.has(remoteName)) return;
const container = instance.moduleCache.get(remoteName);
if (!container.remoteInfo) return;
return container.remoteInfo.entry;
});
if (!container) throw new Error("Container not found");
url = new URL(container.moduleCache.get(remoteName).remoteInfo.entry);
const fileToReplace = path.basename(url.pathname);
url.pathname = url.pathname.replace(fileToReplace, chunkName);
}
(url.protocol === "https:" ? https : http).get(url.href, (res) => {
let data = "";
res.on("data", (chunk) => {
data += chunk.toString();
});
res.on("end", () => {
const chunk = {};
const urlDirname = url.pathname.split("/").slice(0, -1).join("/");
try {
vm.runInThisContext(`(function(exports, require, __dirname, __filename) {${data}\n})`, chunkName)(chunk, __require, urlDirname, chunkName);
callback(null, chunk);
} catch (err) {
callback(err, null);
}
});
res.on("error", (err) => {
callback(err, null);
});
}).on("error", (err) => callback(err, null));
}
//#endregion
export { fileSystemRunInContextStrategy, httpEvalStrategy, httpVmStrategy };
//# sourceMappingURL=stratagies.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,8 @@
import StreamingTargetPlugin from "./plugins/StreamingTargetPlugin.mjs";
import NodeFederationPlugin from "./plugins/NodeFederationPlugin.mjs";
import UniversalFederationPlugin from "./plugins/UniversalFederationPlugin.mjs";
import ChunkCorrelationPlugin from "./plugins/ChunkCorrelationPlugin.mjs";
import AutoPublicPathRuntimeModule from "./plugins/RemotePublicPathRuntimeModule.mjs";
import EntryChunkTrackerPlugin from "./plugins/EntryChunkTrackerPlugin.mjs";
import UniverseEntryChunkTrackerPlugin from "./plugins/UniverseEntryChunkTrackerPlugin.mjs";
export { ChunkCorrelationPlugin, EntryChunkTrackerPlugin, NodeFederationPlugin, AutoPublicPathRuntimeModule as RemotePublicPathPlugin, StreamingTargetPlugin, UniversalFederationPlugin, UniverseEntryChunkTrackerPlugin };

View File

@@ -0,0 +1,8 @@
import StreamingTargetPlugin from "./plugins/StreamingTargetPlugin.js";
import NodeFederationPlugin from "./plugins/NodeFederationPlugin.js";
import UniversalFederationPlugin from "./plugins/UniversalFederationPlugin.js";
import ChunkCorrelationPlugin from "./plugins/ChunkCorrelationPlugin.js";
import AutoPublicPathRuntimeModule from "./plugins/RemotePublicPathRuntimeModule.js";
import EntryChunkTrackerPlugin from "./plugins/EntryChunkTrackerPlugin.js";
import UniverseEntryChunkTrackerPlugin from "./plugins/UniverseEntryChunkTrackerPlugin.js";
export { ChunkCorrelationPlugin, EntryChunkTrackerPlugin, NodeFederationPlugin, AutoPublicPathRuntimeModule as RemotePublicPathPlugin, StreamingTargetPlugin, UniversalFederationPlugin, UniverseEntryChunkTrackerPlugin };

16
node_modules/@module-federation/node/dist/src/index.js generated vendored Normal file
View File

@@ -0,0 +1,16 @@
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const require_src_plugins_RemotePublicPathRuntimeModule = require('./plugins/RemotePublicPathRuntimeModule.js');
const require_src_plugins_StreamingTargetPlugin = require('./plugins/StreamingTargetPlugin.js');
const require_src_plugins_EntryChunkTrackerPlugin = require('./plugins/EntryChunkTrackerPlugin.js');
const require_src_plugins_NodeFederationPlugin = require('./plugins/NodeFederationPlugin.js');
const require_src_plugins_UniversalFederationPlugin = require('./plugins/UniversalFederationPlugin.js');
const require_src_plugins_ChunkCorrelationPlugin = require('./plugins/ChunkCorrelationPlugin.js');
const require_src_plugins_UniverseEntryChunkTrackerPlugin = require('./plugins/UniverseEntryChunkTrackerPlugin.js');
exports.ChunkCorrelationPlugin = require_src_plugins_ChunkCorrelationPlugin.default;
exports.EntryChunkTrackerPlugin = require_src_plugins_EntryChunkTrackerPlugin.default;
exports.NodeFederationPlugin = require_src_plugins_NodeFederationPlugin.default;
exports.RemotePublicPathPlugin = require_src_plugins_RemotePublicPathRuntimeModule.default;
exports.StreamingTargetPlugin = require_src_plugins_StreamingTargetPlugin.default;
exports.UniversalFederationPlugin = require_src_plugins_UniversalFederationPlugin.default;
exports.UniverseEntryChunkTrackerPlugin = require_src_plugins_UniverseEntryChunkTrackerPlugin.default;

View File

@@ -0,0 +1,9 @@
import AutoPublicPathRuntimeModule from "./plugins/RemotePublicPathRuntimeModule.mjs";
import StreamingTargetPlugin from "./plugins/StreamingTargetPlugin.mjs";
import EntryChunkTrackerPlugin from "./plugins/EntryChunkTrackerPlugin.mjs";
import NodeFederationPlugin from "./plugins/NodeFederationPlugin.mjs";
import UniversalFederationPlugin from "./plugins/UniversalFederationPlugin.mjs";
import ChunkCorrelationPlugin from "./plugins/ChunkCorrelationPlugin.mjs";
import UniverseEntryChunkTrackerPlugin from "./plugins/UniverseEntryChunkTrackerPlugin.mjs";
export { ChunkCorrelationPlugin, EntryChunkTrackerPlugin, NodeFederationPlugin, AutoPublicPathRuntimeModule as RemotePublicPathPlugin, StreamingTargetPlugin, UniversalFederationPlugin, UniverseEntryChunkTrackerPlugin };

View File

@@ -0,0 +1,12 @@
import { Compiler } from "webpack";
//#region src/plugins/AutomaticPublicPathPlugin.d.ts
interface PluginOptions {}
declare class RemotePublicPathPlugin {
private options?;
constructor(options?: PluginOptions);
apply(compiler: Compiler): void;
}
//#endregion
export { RemotePublicPathPlugin as default };
//# sourceMappingURL=AutomaticPublicPathPlugin.d.mts.map

View File

@@ -0,0 +1,11 @@
import { Compiler } from "webpack";
//#region src/plugins/AutomaticPublicPathPlugin.d.ts
interface PluginOptions {}
declare class RemotePublicPathPlugin {
private options?;
constructor(options?: PluginOptions);
apply(compiler: Compiler): void;
}
export = RemotePublicPathPlugin;
//# sourceMappingURL=AutomaticPublicPathPlugin.d.ts.map

View File

@@ -0,0 +1,29 @@
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
const require_src_plugins_RemotePublicPathRuntimeModule = require('./RemotePublicPathRuntimeModule.js');
//#region src/plugins/AutomaticPublicPathPlugin.ts
var RemotePublicPathPlugin = class {
constructor(options) {
this.options = options;
}
apply(compiler) {
const { RuntimeGlobals } = compiler.webpack;
compiler.hooks.thisCompilation.tap("RemotePublicPathPlugin", (compilation) => {
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.publicPath).tap("RuntimePlugin", (chunk, set) => {
const { outputOptions } = compilation;
const { publicPath: globalPublicPath, scriptType } = outputOptions;
const entryOptions = chunk.getEntryOptions();
const publicPath = entryOptions && entryOptions.publicPath !== void 0 ? entryOptions.publicPath : globalPublicPath;
const module = new require_src_plugins_RemotePublicPathRuntimeModule.default(this.options);
if (publicPath === "auto" && scriptType !== "module") set.add(RuntimeGlobals.global);
else if (typeof publicPath !== "string" || /\[(full)?hash\]/.test(publicPath)) module.fullHash = true;
compilation.addRuntimeModule(chunk, module);
return true;
});
});
}
};
//#endregion
exports.default = RemotePublicPathPlugin;
//# sourceMappingURL=AutomaticPublicPathPlugin.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"AutomaticPublicPathPlugin.js","names":["RemotePublicPathRuntimeModule"],"sources":["../../../src/plugins/AutomaticPublicPathPlugin.ts"],"sourcesContent":["import type { Compiler } from 'webpack';\n\nimport RemotePublicPathRuntimeModule from './RemotePublicPathRuntimeModule';\n\ninterface PluginOptions {}\n\nclass RemotePublicPathPlugin {\n private options?: PluginOptions;\n\n constructor(options?: PluginOptions) {\n this.options = options;\n }\n\n apply(compiler: Compiler) {\n const { RuntimeGlobals } = compiler.webpack;\n compiler.hooks.thisCompilation.tap(\n 'RemotePublicPathPlugin',\n (compilation) => {\n compilation.hooks.runtimeRequirementInTree\n .for(RuntimeGlobals.publicPath)\n .tap('RuntimePlugin', (chunk, set) => {\n const { outputOptions } = compilation;\n const { publicPath: globalPublicPath, scriptType } = outputOptions;\n const entryOptions = chunk.getEntryOptions();\n const publicPath =\n entryOptions && entryOptions.publicPath !== undefined\n ? entryOptions.publicPath\n : globalPublicPath;\n\n const module = new RemotePublicPathRuntimeModule(this.options);\n if (publicPath === 'auto' && scriptType !== 'module') {\n set.add(RuntimeGlobals.global);\n } else if (\n typeof publicPath !== 'string' ||\n /\\[(full)?hash\\]/.test(publicPath)\n ) {\n module.fullHash = true;\n }\n\n compilation.addRuntimeModule(chunk, module);\n return true;\n });\n },\n );\n }\n}\n\nexport default RemotePublicPathPlugin;\n"],"mappings":";;;;AAMA,IAAM,yBAAN,MAA6B;CAG3B,YAAY,SAAyB;AACnC,OAAK,UAAU;;CAGjB,MAAM,UAAoB;EACxB,MAAM,EAAE,mBAAmB,SAAS;AACpC,WAAS,MAAM,gBAAgB,IAC7B,2BACC,gBAAgB;AACf,eAAY,MAAM,yBACf,IAAI,eAAe,WAAW,CAC9B,IAAI,kBAAkB,OAAO,QAAQ;IACpC,MAAM,EAAE,kBAAkB;IAC1B,MAAM,EAAE,YAAY,kBAAkB,eAAe;IACrD,MAAM,eAAe,MAAM,iBAAiB;IAC5C,MAAM,aACJ,gBAAgB,aAAa,eAAe,SACxC,aAAa,aACb;IAEN,MAAM,SAAS,IAAIA,0DAA8B,KAAK,QAAQ;AAC9D,QAAI,eAAe,UAAU,eAAe,SAC1C,KAAI,IAAI,eAAe,OAAO;aAE9B,OAAO,eAAe,YACtB,kBAAkB,KAAK,WAAW,CAElC,QAAO,WAAW;AAGpB,gBAAY,iBAAiB,OAAO,OAAO;AAC3C,WAAO;KACP;IAEP"}

View File

@@ -0,0 +1,28 @@
import AutoPublicPathRuntimeModule from "./RemotePublicPathRuntimeModule.mjs";
//#region src/plugins/AutomaticPublicPathPlugin.ts
var RemotePublicPathPlugin = class {
constructor(options) {
this.options = options;
}
apply(compiler) {
const { RuntimeGlobals } = compiler.webpack;
compiler.hooks.thisCompilation.tap("RemotePublicPathPlugin", (compilation) => {
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.publicPath).tap("RuntimePlugin", (chunk, set) => {
const { outputOptions } = compilation;
const { publicPath: globalPublicPath, scriptType } = outputOptions;
const entryOptions = chunk.getEntryOptions();
const publicPath = entryOptions && entryOptions.publicPath !== void 0 ? entryOptions.publicPath : globalPublicPath;
const module = new AutoPublicPathRuntimeModule(this.options);
if (publicPath === "auto" && scriptType !== "module") set.add(RuntimeGlobals.global);
else if (typeof publicPath !== "string" || /\[(full)?hash\]/.test(publicPath)) module.fullHash = true;
compilation.addRuntimeModule(chunk, module);
return true;
});
});
}
};
//#endregion
export { RemotePublicPathPlugin as default };
//# sourceMappingURL=AutomaticPublicPathPlugin.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"AutomaticPublicPathPlugin.mjs","names":["RemotePublicPathRuntimeModule"],"sources":["../../../src/plugins/AutomaticPublicPathPlugin.ts"],"sourcesContent":["import type { Compiler } from 'webpack';\n\nimport RemotePublicPathRuntimeModule from './RemotePublicPathRuntimeModule';\n\ninterface PluginOptions {}\n\nclass RemotePublicPathPlugin {\n private options?: PluginOptions;\n\n constructor(options?: PluginOptions) {\n this.options = options;\n }\n\n apply(compiler: Compiler) {\n const { RuntimeGlobals } = compiler.webpack;\n compiler.hooks.thisCompilation.tap(\n 'RemotePublicPathPlugin',\n (compilation) => {\n compilation.hooks.runtimeRequirementInTree\n .for(RuntimeGlobals.publicPath)\n .tap('RuntimePlugin', (chunk, set) => {\n const { outputOptions } = compilation;\n const { publicPath: globalPublicPath, scriptType } = outputOptions;\n const entryOptions = chunk.getEntryOptions();\n const publicPath =\n entryOptions && entryOptions.publicPath !== undefined\n ? entryOptions.publicPath\n : globalPublicPath;\n\n const module = new RemotePublicPathRuntimeModule(this.options);\n if (publicPath === 'auto' && scriptType !== 'module') {\n set.add(RuntimeGlobals.global);\n } else if (\n typeof publicPath !== 'string' ||\n /\\[(full)?hash\\]/.test(publicPath)\n ) {\n module.fullHash = true;\n }\n\n compilation.addRuntimeModule(chunk, module);\n return true;\n });\n },\n );\n }\n}\n\nexport default RemotePublicPathPlugin;\n"],"mappings":";;;AAMA,IAAM,yBAAN,MAA6B;CAG3B,YAAY,SAAyB;AACnC,OAAK,UAAU;;CAGjB,MAAM,UAAoB;EACxB,MAAM,EAAE,mBAAmB,SAAS;AACpC,WAAS,MAAM,gBAAgB,IAC7B,2BACC,gBAAgB;AACf,eAAY,MAAM,yBACf,IAAI,eAAe,WAAW,CAC9B,IAAI,kBAAkB,OAAO,QAAQ;IACpC,MAAM,EAAE,kBAAkB;IAC1B,MAAM,EAAE,YAAY,kBAAkB,eAAe;IACrD,MAAM,eAAe,MAAM,iBAAiB;IAC5C,MAAM,aACJ,gBAAgB,aAAa,eAAe,SACxC,aAAa,aACb;IAEN,MAAM,SAAS,IAAIA,4BAA8B,KAAK,QAAQ;AAC9D,QAAI,eAAe,UAAU,eAAe,SAC1C,KAAI,IAAI,eAAe,OAAO;aAE9B,OAAO,eAAe,YACtB,kBAAkB,KAAK,WAAW,CAElC,QAAO,WAAW;AAGpB,gBAAY,iBAAiB,OAAO,OAAO;AAC3C,WAAO;KACP;IAEP"}

View File

@@ -0,0 +1,5 @@
//#region src/plugins/ChunkCorrelationPlugin.d.ts
declare const ChunkCorrelationPlugin: any;
//#endregion
export { ChunkCorrelationPlugin as default };
//# sourceMappingURL=ChunkCorrelationPlugin.d.mts.map

View File

@@ -0,0 +1,4 @@
//#region src/plugins/ChunkCorrelationPlugin.d.ts
declare const ChunkCorrelationPlugin: any;
export = ChunkCorrelationPlugin;
//# sourceMappingURL=ChunkCorrelationPlugin.d.ts.map

View File

@@ -0,0 +1,9 @@
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
const require_ChunkCorrelationPlugin$1 = require('../../plugins/ChunkCorrelationPlugin.js');
//#region src/plugins/ChunkCorrelationPlugin.ts
const ChunkCorrelationPlugin = require_ChunkCorrelationPlugin$1.default;
//#endregion
exports.default = ChunkCorrelationPlugin;
//# sourceMappingURL=ChunkCorrelationPlugin.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ChunkCorrelationPlugin.js","names":[],"sources":["../../../src/plugins/ChunkCorrelationPlugin.ts"],"sourcesContent":["// Preserve existing CommonJS implementation while exposing a TS default export\n// that tsdown can analyze for dual-format output.\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst ChunkCorrelationPlugin = require('./ChunkCorrelationPlugin.js');\n\nexport default ChunkCorrelationPlugin;\n"],"mappings":";;;;AAGA,MAAM"}

View File

@@ -0,0 +1,8 @@
import { require_ChunkCorrelationPlugin } from "../../plugins/ChunkCorrelationPlugin.mjs";
//#region src/plugins/ChunkCorrelationPlugin.ts
const ChunkCorrelationPlugin = require_ChunkCorrelationPlugin();
//#endregion
export { ChunkCorrelationPlugin as default };
//# sourceMappingURL=ChunkCorrelationPlugin.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ChunkCorrelationPlugin.mjs","names":[],"sources":["../../../src/plugins/ChunkCorrelationPlugin.ts"],"sourcesContent":["// Preserve existing CommonJS implementation while exposing a TS default export\n// that tsdown can analyze for dual-format output.\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst ChunkCorrelationPlugin = require('./ChunkCorrelationPlugin.js');\n\nexport default ChunkCorrelationPlugin;\n"],"mappings":";;;AAGA,MAAM"}

View File

@@ -0,0 +1,21 @@
import { ModuleFederationPluginOptions } from "../types/index.mjs";
import { Compiler } from "webpack";
//#region src/plugins/CommonJsChunkLoadingPlugin.d.ts
interface DynamicFilesystemChunkLoadingOptions extends ModuleFederationPluginOptions {
baseURI: Compiler['options']['output']['publicPath'];
promiseBaseURI?: string;
remotes: Record<string, string>;
name?: string;
asyncChunkLoading: boolean;
debug?: boolean;
}
declare class DynamicFilesystemChunkLoadingPlugin {
private options;
private _asyncChunkLoading;
constructor(options: DynamicFilesystemChunkLoadingOptions);
apply(compiler: Compiler): void;
}
//#endregion
export { DynamicFilesystemChunkLoadingPlugin as default };
//# sourceMappingURL=CommonJsChunkLoadingPlugin.d.mts.map

View File

@@ -0,0 +1,20 @@
import { ModuleFederationPluginOptions } from "../types/index.js";
import { Compiler } from "webpack";
//#region src/plugins/CommonJsChunkLoadingPlugin.d.ts
interface DynamicFilesystemChunkLoadingOptions extends ModuleFederationPluginOptions {
baseURI: Compiler['options']['output']['publicPath'];
promiseBaseURI?: string;
remotes: Record<string, string>;
name?: string;
asyncChunkLoading: boolean;
debug?: boolean;
}
declare class DynamicFilesystemChunkLoadingPlugin {
private options;
private _asyncChunkLoading;
constructor(options: DynamicFilesystemChunkLoadingOptions);
apply(compiler: Compiler): void;
}
export = DynamicFilesystemChunkLoadingPlugin;
//# sourceMappingURL=CommonJsChunkLoadingPlugin.d.ts.map

View File

@@ -0,0 +1,71 @@
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
const require_runtime = require('../../_virtual/_rolldown/runtime.js');
const require_src_plugins_DynamicFilesystemChunkLoadingRuntimeModule = require('./DynamicFilesystemChunkLoadingRuntimeModule.js');
const require_src_plugins_RemotePublicPathRuntimeModule = require('./RemotePublicPathRuntimeModule.js');
let _module_federation_sdk_normalize_webpack_path = require("@module-federation/sdk/normalize-webpack-path");
//#region src/plugins/CommonJsChunkLoadingPlugin.ts
const StartupChunkDependenciesPlugin = require((0, _module_federation_sdk_normalize_webpack_path.normalizeWebpackPath)("webpack/lib/runtime/StartupChunkDependenciesPlugin"));
var DynamicFilesystemChunkLoadingPlugin = class {
constructor(options) {
this.options = options || {};
this._asyncChunkLoading = this.options.asyncChunkLoading;
}
apply(compiler) {
const { RuntimeGlobals } = compiler.webpack;
new StartupChunkDependenciesPlugin({
chunkLoading: this._asyncChunkLoading ? "async-node" : "require",
asyncChunkLoading: this._asyncChunkLoading
}).apply(compiler);
compiler.hooks.thisCompilation.tap("DynamicFilesystemChunkLoadingPlugin", (compilation) => {
const isEnabledForChunk = (_) => true;
const onceForChunkSet = /* @__PURE__ */ new WeakSet();
const handler = (chunk, set) => {
if (onceForChunkSet.has(chunk)) return;
onceForChunkSet.add(chunk);
if (!isEnabledForChunk(chunk)) return;
set.add(RuntimeGlobals.moduleFactoriesAddOnly);
set.add(RuntimeGlobals.hasOwnProperty);
set.add(RuntimeGlobals.publicPath);
compilation.addRuntimeModule(chunk, new require_src_plugins_DynamicFilesystemChunkLoadingRuntimeModule.default(set, this.options, { webpack: compiler.webpack }));
};
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.ensureChunkHandlers).tap("DynamicFilesystemChunkLoadingPlugin", handler);
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.hmrDownloadUpdateHandlers).tap("DynamicFilesystemChunkLoadingPlugin", handler);
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.hmrDownloadManifest).tap("DynamicFilesystemChunkLoadingPlugin", handler);
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.baseURI).tap("DynamicFilesystemChunkLoadingPlugin", handler);
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.externalInstallChunk).tap("DynamicFilesystemChunkLoadingPlugin", handler);
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.onChunksLoaded).tap("DynamicFilesystemChunkLoadingPlugin", handler);
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.ensureChunkHandlers).tap("DynamicFilesystemChunkLoadingPlugin", (chunk, set) => {
if (!isEnabledForChunk(chunk)) return;
set.add(RuntimeGlobals.getChunkScriptFilename);
});
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.hmrDownloadUpdateHandlers).tap("DynamicFilesystemChunkLoadingPlugin", (chunk, set) => {
if (!isEnabledForChunk(chunk)) return;
set.add(RuntimeGlobals.getChunkUpdateScriptFilename);
set.add(RuntimeGlobals.moduleCache);
set.add(RuntimeGlobals.hmrModuleData);
set.add(RuntimeGlobals.moduleFactoriesAddOnly);
});
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.hmrDownloadManifest).tap("DynamicFilesystemChunkLoadingPlugin", (chunk, set) => {
if (!isEnabledForChunk(chunk)) return;
set.add(RuntimeGlobals.getUpdateManifestFilename);
});
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.publicPath).tap("RuntimePlugin", (chunk, set) => {
const { outputOptions } = compilation;
const { publicPath: globalPublicPath, scriptType } = outputOptions;
const entryOptions = chunk.getEntryOptions();
const publicPath = entryOptions && entryOptions.publicPath !== void 0 ? entryOptions.publicPath : globalPublicPath;
const module = new require_src_plugins_RemotePublicPathRuntimeModule.default(this.options);
if (publicPath === "auto" && scriptType !== "module") set.add(RuntimeGlobals.global);
else if (typeof publicPath !== "string" || /\[(full)?hash\]/.test(publicPath)) module.fullHash = true;
compilation.addRuntimeModule(chunk, module);
return true;
});
compilation.hooks.additionalTreeRuntimeRequirements.tap("StartupChunkDependenciesPlugin", (chunk, set, { chunkGraph }) => {});
});
}
};
//#endregion
exports.default = DynamicFilesystemChunkLoadingPlugin;
//# sourceMappingURL=CommonJsChunkLoadingPlugin.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,70 @@
import { __require } from "../../_virtual/_rolldown/runtime.mjs";
import DynamicFilesystemChunkLoadingRuntimeModule from "./DynamicFilesystemChunkLoadingRuntimeModule.mjs";
import AutoPublicPathRuntimeModule from "./RemotePublicPathRuntimeModule.mjs";
import { normalizeWebpackPath } from "@module-federation/sdk/normalize-webpack-path";
//#region src/plugins/CommonJsChunkLoadingPlugin.ts
const StartupChunkDependenciesPlugin = __require(normalizeWebpackPath("webpack/lib/runtime/StartupChunkDependenciesPlugin"));
var DynamicFilesystemChunkLoadingPlugin = class {
constructor(options) {
this.options = options || {};
this._asyncChunkLoading = this.options.asyncChunkLoading;
}
apply(compiler) {
const { RuntimeGlobals } = compiler.webpack;
new StartupChunkDependenciesPlugin({
chunkLoading: this._asyncChunkLoading ? "async-node" : "require",
asyncChunkLoading: this._asyncChunkLoading
}).apply(compiler);
compiler.hooks.thisCompilation.tap("DynamicFilesystemChunkLoadingPlugin", (compilation) => {
const isEnabledForChunk = (_) => true;
const onceForChunkSet = /* @__PURE__ */ new WeakSet();
const handler = (chunk, set) => {
if (onceForChunkSet.has(chunk)) return;
onceForChunkSet.add(chunk);
if (!isEnabledForChunk(chunk)) return;
set.add(RuntimeGlobals.moduleFactoriesAddOnly);
set.add(RuntimeGlobals.hasOwnProperty);
set.add(RuntimeGlobals.publicPath);
compilation.addRuntimeModule(chunk, new DynamicFilesystemChunkLoadingRuntimeModule(set, this.options, { webpack: compiler.webpack }));
};
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.ensureChunkHandlers).tap("DynamicFilesystemChunkLoadingPlugin", handler);
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.hmrDownloadUpdateHandlers).tap("DynamicFilesystemChunkLoadingPlugin", handler);
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.hmrDownloadManifest).tap("DynamicFilesystemChunkLoadingPlugin", handler);
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.baseURI).tap("DynamicFilesystemChunkLoadingPlugin", handler);
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.externalInstallChunk).tap("DynamicFilesystemChunkLoadingPlugin", handler);
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.onChunksLoaded).tap("DynamicFilesystemChunkLoadingPlugin", handler);
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.ensureChunkHandlers).tap("DynamicFilesystemChunkLoadingPlugin", (chunk, set) => {
if (!isEnabledForChunk(chunk)) return;
set.add(RuntimeGlobals.getChunkScriptFilename);
});
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.hmrDownloadUpdateHandlers).tap("DynamicFilesystemChunkLoadingPlugin", (chunk, set) => {
if (!isEnabledForChunk(chunk)) return;
set.add(RuntimeGlobals.getChunkUpdateScriptFilename);
set.add(RuntimeGlobals.moduleCache);
set.add(RuntimeGlobals.hmrModuleData);
set.add(RuntimeGlobals.moduleFactoriesAddOnly);
});
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.hmrDownloadManifest).tap("DynamicFilesystemChunkLoadingPlugin", (chunk, set) => {
if (!isEnabledForChunk(chunk)) return;
set.add(RuntimeGlobals.getUpdateManifestFilename);
});
compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.publicPath).tap("RuntimePlugin", (chunk, set) => {
const { outputOptions } = compilation;
const { publicPath: globalPublicPath, scriptType } = outputOptions;
const entryOptions = chunk.getEntryOptions();
const publicPath = entryOptions && entryOptions.publicPath !== void 0 ? entryOptions.publicPath : globalPublicPath;
const module = new AutoPublicPathRuntimeModule(this.options);
if (publicPath === "auto" && scriptType !== "module") set.add(RuntimeGlobals.global);
else if (typeof publicPath !== "string" || /\[(full)?hash\]/.test(publicPath)) module.fullHash = true;
compilation.addRuntimeModule(chunk, module);
return true;
});
compilation.hooks.additionalTreeRuntimeRequirements.tap("StartupChunkDependenciesPlugin", (chunk, set, { chunkGraph }) => {});
});
}
};
//#endregion
export { DynamicFilesystemChunkLoadingPlugin as default };
//# sourceMappingURL=CommonJsChunkLoadingPlugin.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,46 @@
import * as tapable from "tapable";
import { SyncWaterfallHook } from "tapable";
import * as webpack from "webpack";
import { Chunk, Compiler } from "webpack";
//#region src/plugins/DynamicFilesystemChunkLoadingRuntimeModule.d.ts
declare const RuntimeModule: typeof webpack.RuntimeModule;
interface DynamicFilesystemChunkLoadingRuntimeModuleOptions {
baseURI: Compiler['options']['output']['publicPath'];
promiseBaseURI?: string;
remotes: Record<string, string>;
name?: string;
debug?: boolean;
}
interface ChunkLoadingContext {
webpack: Compiler['webpack'];
}
declare class DynamicFilesystemChunkLoadingRuntimeModule extends RuntimeModule {
private runtimeRequirements;
private options;
private chunkLoadingContext;
hooks: {
strategyCase: SyncWaterfallHook<unknown, unknown, tapable.UnsetAdditionalOptions>;
};
private logger;
constructor(runtimeRequirements: Set<string>, options: DynamicFilesystemChunkLoadingRuntimeModuleOptions, chunkLoadingContext: ChunkLoadingContext);
/**
* @private
* @param {Chunk} chunk chunk
* @param {string} rootOutputDir root output directory
* @returns {string} generated code
*/
_generateBaseUri(chunk: Chunk, rootOutputDir: string): string;
/**
* @private
* @param {unknown[]} items item to log
*/
_getLogger(...items: unknown[]): string;
/**
* @returns {string} runtime code
*/
generate(): string;
}
//#endregion
export { DynamicFilesystemChunkLoadingRuntimeModule as default };
//# sourceMappingURL=DynamicFilesystemChunkLoadingRuntimeModule.d.mts.map

View File

@@ -0,0 +1,45 @@
import * as webpack from "webpack";
import { Chunk, Compiler } from "webpack";
import * as tapable from "tapable";
import { SyncWaterfallHook } from "tapable";
//#region src/plugins/DynamicFilesystemChunkLoadingRuntimeModule.d.ts
declare const RuntimeModule: typeof webpack.RuntimeModule;
interface DynamicFilesystemChunkLoadingRuntimeModuleOptions {
baseURI: Compiler['options']['output']['publicPath'];
promiseBaseURI?: string;
remotes: Record<string, string>;
name?: string;
debug?: boolean;
}
interface ChunkLoadingContext {
webpack: Compiler['webpack'];
}
declare class DynamicFilesystemChunkLoadingRuntimeModule extends RuntimeModule {
private runtimeRequirements;
private options;
private chunkLoadingContext;
hooks: {
strategyCase: SyncWaterfallHook<unknown, unknown, tapable.UnsetAdditionalOptions>;
};
private logger;
constructor(runtimeRequirements: Set<string>, options: DynamicFilesystemChunkLoadingRuntimeModuleOptions, chunkLoadingContext: ChunkLoadingContext);
/**
* @private
* @param {Chunk} chunk chunk
* @param {string} rootOutputDir root output directory
* @returns {string} generated code
*/
_generateBaseUri(chunk: Chunk, rootOutputDir: string): string;
/**
* @private
* @param {unknown[]} items item to log
*/
_getLogger(...items: unknown[]): string;
/**
* @returns {string} runtime code
*/
generate(): string;
}
export = DynamicFilesystemChunkLoadingRuntimeModule;
//# sourceMappingURL=DynamicFilesystemChunkLoadingRuntimeModule.d.ts.map

View File

@@ -0,0 +1,112 @@
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
const require_runtime = require('../../_virtual/_rolldown/runtime.js');
const require_src_plugins_webpackChunkUtilities = require('./webpackChunkUtilities.js');
const require_src_filesystem_stratagies = require('../filesystem/stratagies.js');
let _module_federation_sdk_normalize_webpack_path = require("@module-federation/sdk/normalize-webpack-path");
let tapable = require("tapable");
let _module_federation_sdk = require("@module-federation/sdk");
//#region src/plugins/DynamicFilesystemChunkLoadingRuntimeModule.ts
const { RuntimeGlobals, RuntimeModule } = require((0, _module_federation_sdk_normalize_webpack_path.normalizeWebpackPath)("webpack"));
const { getUndoPath } = require((0, _module_federation_sdk_normalize_webpack_path.normalizeWebpackPath)("webpack/lib/util/identifier"));
const compileBooleanMatcher = require((0, _module_federation_sdk_normalize_webpack_path.normalizeWebpackPath)("webpack/lib/util/compileBooleanMatcher"));
const createBundlerLogger = typeof _module_federation_sdk.createInfrastructureLogger === "function" ? _module_federation_sdk.createInfrastructureLogger : _module_federation_sdk.createLogger;
var DynamicFilesystemChunkLoadingRuntimeModule = class extends RuntimeModule {
constructor(runtimeRequirements, options, chunkLoadingContext) {
super("readFile chunk loading", RuntimeModule.STAGE_ATTACH + 1);
this.hooks = { strategyCase: new tapable.SyncWaterfallHook(["source"]) };
this.logger = createBundlerLogger("[ DynamicFilesystemChunkLoadingRuntimeModule ]");
this.runtimeRequirements = runtimeRequirements;
this.options = options;
this.chunkLoadingContext = chunkLoadingContext;
}
/**
* @private
* @param {Chunk} chunk chunk
* @param {string} rootOutputDir root output directory
* @returns {string} generated code
*/
_generateBaseUri(chunk, rootOutputDir) {
const options = chunk.getEntryOptions();
if (options && options.baseUri) return `${RuntimeGlobals.baseURI} = ${JSON.stringify(options.baseUri)};`;
return `${RuntimeGlobals.baseURI} = require("url").pathToFileURL(${rootOutputDir ? `__dirname + ${JSON.stringify("/" + rootOutputDir)}` : "__filename"});`;
}
/**
* @private
* @param {unknown[]} items item to log
*/
_getLogger(...items) {
if (!this.options.debug) return "";
return `console.log(${items.join(",")});`;
}
/**
* @returns {string} runtime code
*/
generate() {
const { remotes = {}, name } = this.options;
const { webpack } = this.chunkLoadingContext;
const { chunkGraph, chunk, compilation } = this;
const { Template } = webpack;
if (!chunkGraph || !chunk || !compilation) {
this.logger.warn("Missing required properties. Returning empty string.");
return "";
}
const infrastructureLogger = compilation.getLogger?.("DynamicFilesystemChunkLoadingRuntimeModule");
if (infrastructureLogger) this.logger.setDelegate(infrastructureLogger);
const { runtimeTemplate } = compilation;
const jsModulePlugin = webpack?.javascript?.JavascriptModulesPlugin || require("webpack/lib/javascript/JavascriptModulesPlugin");
const { chunkHasJs } = jsModulePlugin;
const fn = RuntimeGlobals.ensureChunkHandlers;
const hasJsMatcher = compileBooleanMatcher(chunkGraph.getChunkConditionMap(chunk, chunkHasJs));
const initialChunkIds = require_src_plugins_webpackChunkUtilities.getInitialChunkIds(chunk, chunkGraph, chunkHasJs);
const rootOutputDir = getUndoPath(compilation.getPath(jsModulePlugin.getChunkFilenameTemplate(chunk, compilation.outputOptions), {
chunk,
contentHashType: "javascript"
}), compilation.outputOptions.path || "", false);
const stateExpression = this.runtimeRequirements.has(RuntimeGlobals.hmrDownloadUpdateHandlers) ? `${RuntimeGlobals.hmrRuntimeStatePrefix}_readFileVm` : void 0;
const dynamicFilesystemChunkLoadingPluginCode = Template.asString([
require_src_filesystem_stratagies.fileSystemRunInContextStrategy.toString(),
require_src_filesystem_stratagies.httpEvalStrategy.toString(),
require_src_filesystem_stratagies.httpVmStrategy.toString(),
"const loadChunkStrategy = async (strategyType,chunkId,rootOutputDir, remotes, callback) => {",
Template.indent([
"switch (strategyType) {",
Template.indent([
"case \"filesystem\": return await fileSystemRunInContextStrategy(chunkId,rootOutputDir, remotes, callback);",
"case \"http-eval\": return await httpEvalStrategy(chunkId,rootOutputDir, remotes, callback);",
"case \"http-vm\": return await httpVmStrategy(chunkId,rootOutputDir, remotes, callback);",
this.hooks.strategyCase.call("default: throw new Error(\"Invalid strategy type\");")
]),
"}"
]),
"};"
]);
return Template.asString([
dynamicFilesystemChunkLoadingPluginCode,
this.runtimeRequirements.has(RuntimeGlobals.baseURI) ? this._generateBaseUri(chunk, rootOutputDir) : "// no baseURI",
"",
"// object to store loaded chunks",
"// \"0\" means \"already loaded\", Promise means loading",
`var installedChunks = ${stateExpression ? `${stateExpression} = ${stateExpression} || ` : ""}{`,
Template.indent(Array.from(initialChunkIds, (id) => `${JSON.stringify(id)}: 0`).join(",\n")),
"};",
"",
require_src_plugins_webpackChunkUtilities.handleOnChunkLoad(this.runtimeRequirements.has(RuntimeGlobals.onChunksLoaded), runtimeTemplate),
"",
require_src_plugins_webpackChunkUtilities.generateInstallChunk(runtimeTemplate, this.runtimeRequirements.has(RuntimeGlobals.onChunksLoaded)),
"",
this.runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers) ? require_src_plugins_webpackChunkUtilities.generateLoadScript(runtimeTemplate) : "// no remote script loader needed",
this.runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers) ? require_src_plugins_webpackChunkUtilities.generateLoadingCode(this.runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers), fn, hasJsMatcher, rootOutputDir, remotes, name) : "// no chunk loading",
"",
require_src_plugins_webpackChunkUtilities.generateExternalInstallChunkCode(this.runtimeRequirements.has(RuntimeGlobals.externalInstallChunk), this.options.debug),
"",
require_src_plugins_webpackChunkUtilities.generateHmrCode(this.runtimeRequirements.has(RuntimeGlobals.hmrDownloadUpdateHandlers), rootOutputDir),
"",
require_src_plugins_webpackChunkUtilities.generateHmrManifestCode(this.runtimeRequirements.has(RuntimeGlobals.hmrDownloadManifest), rootOutputDir)
]);
}
};
//#endregion
exports.default = DynamicFilesystemChunkLoadingRuntimeModule;
//# sourceMappingURL=DynamicFilesystemChunkLoadingRuntimeModule.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,111 @@
import { __require } from "../../_virtual/_rolldown/runtime.mjs";
import { generateExternalInstallChunkCode, generateHmrCode, generateHmrManifestCode, generateInstallChunk, generateLoadScript, generateLoadingCode, getInitialChunkIds, handleOnChunkLoad } from "./webpackChunkUtilities.mjs";
import { fileSystemRunInContextStrategy, httpEvalStrategy, httpVmStrategy } from "../filesystem/stratagies.mjs";
import { normalizeWebpackPath } from "@module-federation/sdk/normalize-webpack-path";
import { SyncWaterfallHook } from "tapable";
import { createInfrastructureLogger, createLogger } from "@module-federation/sdk";
//#region src/plugins/DynamicFilesystemChunkLoadingRuntimeModule.ts
const { RuntimeGlobals, RuntimeModule } = __require(normalizeWebpackPath("webpack"));
const { getUndoPath } = __require(normalizeWebpackPath("webpack/lib/util/identifier"));
const compileBooleanMatcher = __require(normalizeWebpackPath("webpack/lib/util/compileBooleanMatcher"));
const createBundlerLogger = typeof createInfrastructureLogger === "function" ? createInfrastructureLogger : createLogger;
var DynamicFilesystemChunkLoadingRuntimeModule = class extends RuntimeModule {
constructor(runtimeRequirements, options, chunkLoadingContext) {
super("readFile chunk loading", RuntimeModule.STAGE_ATTACH + 1);
this.hooks = { strategyCase: new SyncWaterfallHook(["source"]) };
this.logger = createBundlerLogger("[ DynamicFilesystemChunkLoadingRuntimeModule ]");
this.runtimeRequirements = runtimeRequirements;
this.options = options;
this.chunkLoadingContext = chunkLoadingContext;
}
/**
* @private
* @param {Chunk} chunk chunk
* @param {string} rootOutputDir root output directory
* @returns {string} generated code
*/
_generateBaseUri(chunk, rootOutputDir) {
const options = chunk.getEntryOptions();
if (options && options.baseUri) return `${RuntimeGlobals.baseURI} = ${JSON.stringify(options.baseUri)};`;
return `${RuntimeGlobals.baseURI} = require("url").pathToFileURL(${rootOutputDir ? `__dirname + ${JSON.stringify("/" + rootOutputDir)}` : "__filename"});`;
}
/**
* @private
* @param {unknown[]} items item to log
*/
_getLogger(...items) {
if (!this.options.debug) return "";
return `console.log(${items.join(",")});`;
}
/**
* @returns {string} runtime code
*/
generate() {
const { remotes = {}, name } = this.options;
const { webpack } = this.chunkLoadingContext;
const { chunkGraph, chunk, compilation } = this;
const { Template } = webpack;
if (!chunkGraph || !chunk || !compilation) {
this.logger.warn("Missing required properties. Returning empty string.");
return "";
}
const infrastructureLogger = compilation.getLogger?.("DynamicFilesystemChunkLoadingRuntimeModule");
if (infrastructureLogger) this.logger.setDelegate(infrastructureLogger);
const { runtimeTemplate } = compilation;
const jsModulePlugin = webpack?.javascript?.JavascriptModulesPlugin || __require("webpack/lib/javascript/JavascriptModulesPlugin");
const { chunkHasJs } = jsModulePlugin;
const fn = RuntimeGlobals.ensureChunkHandlers;
const hasJsMatcher = compileBooleanMatcher(chunkGraph.getChunkConditionMap(chunk, chunkHasJs));
const initialChunkIds = getInitialChunkIds(chunk, chunkGraph, chunkHasJs);
const rootOutputDir = getUndoPath(compilation.getPath(jsModulePlugin.getChunkFilenameTemplate(chunk, compilation.outputOptions), {
chunk,
contentHashType: "javascript"
}), compilation.outputOptions.path || "", false);
const stateExpression = this.runtimeRequirements.has(RuntimeGlobals.hmrDownloadUpdateHandlers) ? `${RuntimeGlobals.hmrRuntimeStatePrefix}_readFileVm` : void 0;
const dynamicFilesystemChunkLoadingPluginCode = Template.asString([
fileSystemRunInContextStrategy.toString(),
httpEvalStrategy.toString(),
httpVmStrategy.toString(),
"const loadChunkStrategy = async (strategyType,chunkId,rootOutputDir, remotes, callback) => {",
Template.indent([
"switch (strategyType) {",
Template.indent([
"case \"filesystem\": return await fileSystemRunInContextStrategy(chunkId,rootOutputDir, remotes, callback);",
"case \"http-eval\": return await httpEvalStrategy(chunkId,rootOutputDir, remotes, callback);",
"case \"http-vm\": return await httpVmStrategy(chunkId,rootOutputDir, remotes, callback);",
this.hooks.strategyCase.call("default: throw new Error(\"Invalid strategy type\");")
]),
"}"
]),
"};"
]);
return Template.asString([
dynamicFilesystemChunkLoadingPluginCode,
this.runtimeRequirements.has(RuntimeGlobals.baseURI) ? this._generateBaseUri(chunk, rootOutputDir) : "// no baseURI",
"",
"// object to store loaded chunks",
"// \"0\" means \"already loaded\", Promise means loading",
`var installedChunks = ${stateExpression ? `${stateExpression} = ${stateExpression} || ` : ""}{`,
Template.indent(Array.from(initialChunkIds, (id) => `${JSON.stringify(id)}: 0`).join(",\n")),
"};",
"",
handleOnChunkLoad(this.runtimeRequirements.has(RuntimeGlobals.onChunksLoaded), runtimeTemplate),
"",
generateInstallChunk(runtimeTemplate, this.runtimeRequirements.has(RuntimeGlobals.onChunksLoaded)),
"",
this.runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers) ? generateLoadScript(runtimeTemplate) : "// no remote script loader needed",
this.runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers) ? generateLoadingCode(this.runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers), fn, hasJsMatcher, rootOutputDir, remotes, name) : "// no chunk loading",
"",
generateExternalInstallChunkCode(this.runtimeRequirements.has(RuntimeGlobals.externalInstallChunk), this.options.debug),
"",
generateHmrCode(this.runtimeRequirements.has(RuntimeGlobals.hmrDownloadUpdateHandlers), rootOutputDir),
"",
generateHmrManifestCode(this.runtimeRequirements.has(RuntimeGlobals.hmrDownloadManifest), rootOutputDir)
]);
}
};
//#endregion
export { DynamicFilesystemChunkLoadingRuntimeModule as default };
//# sourceMappingURL=DynamicFilesystemChunkLoadingRuntimeModule.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,17 @@
import { Chunk, Compiler, Module } from "webpack";
//#region src/plugins/EntryChunkTrackerPlugin.d.ts
interface Options {
eager?: RegExp | ((module: Module) => boolean);
excludeChunk?: (chunk: Chunk) => boolean;
}
declare class EntryChunkTrackerPlugin {
private _options;
constructor(options?: Options);
apply(compiler: Compiler): void;
private _handleRenderStartup;
private _getTemplateString;
}
//#endregion
export { Options, EntryChunkTrackerPlugin as default };
//# sourceMappingURL=EntryChunkTrackerPlugin.d.mts.map

View File

@@ -0,0 +1,17 @@
import { Chunk, Compiler, Module } from "webpack";
//#region src/plugins/EntryChunkTrackerPlugin.d.ts
interface Options {
eager?: RegExp | ((module: Module) => boolean);
excludeChunk?: (chunk: Chunk) => boolean;
}
declare class EntryChunkTrackerPlugin {
private _options;
constructor(options?: Options);
apply(compiler: Compiler): void;
private _handleRenderStartup;
private _getTemplateString;
}
//#endregion
export { Options, EntryChunkTrackerPlugin as default };
//# sourceMappingURL=EntryChunkTrackerPlugin.d.ts.map

View File

@@ -0,0 +1,39 @@
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
const require_runtime = require('../../_virtual/_rolldown/runtime.js');
let _module_federation_sdk_normalize_webpack_path = require("@module-federation/sdk/normalize-webpack-path");
//#region src/plugins/EntryChunkTrackerPlugin.ts
require((0, _module_federation_sdk_normalize_webpack_path.normalizeWebpackPath)("webpack/lib/util/SortableSet"));
var EntryChunkTrackerPlugin = class {
constructor(options) {
this._options = options || {};
}
apply(compiler) {
compiler.hooks.thisCompilation.tap("EntryChunkTrackerPlugin", (compilation) => {
this._handleRenderStartup(compiler, compilation);
});
}
_handleRenderStartup(compiler, compilation) {
compiler.webpack.javascript.JavascriptModulesPlugin.getCompilationHooks(compilation).renderStartup.tap("EntryChunkTrackerPlugin", (source, _renderContext, upperContext) => {
if (this._options.excludeChunk && this._options.excludeChunk(upperContext.chunk)) return source;
const templateString = this._getTemplateString(compiler, source);
return new compiler.webpack.sources.ConcatSource(templateString);
});
}
_getTemplateString(compiler, source) {
const { Template } = compiler.webpack;
return Template.asString([`if(typeof module !== 'undefined') {
globalThis.entryChunkCache = globalThis.entryChunkCache || new Set();
module.filename && globalThis.entryChunkCache.add(module.filename);
if(module.children) {
module.children.forEach(function(c) {
c.filename && globalThis.entryChunkCache.add(c.filename);
})
}
}`, Template.indent(source.source().toString())]);
}
};
//#endregion
exports.default = EntryChunkTrackerPlugin;
//# sourceMappingURL=EntryChunkTrackerPlugin.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"EntryChunkTrackerPlugin.js","names":[],"sources":["../../../src/plugins/EntryChunkTrackerPlugin.ts"],"sourcesContent":["import { normalizeWebpackPath } from '@module-federation/sdk/normalize-webpack-path';\nimport type {\n Compiler,\n Compilation,\n Chunk,\n sources,\n Module,\n RuntimeGlobals,\n javascript,\n} from 'webpack';\nimport type { SyncWaterfallHook } from 'tapable';\n\nconst SortableSet = require(\n normalizeWebpackPath('webpack/lib/util/SortableSet'),\n) as typeof import('webpack/lib/util/SortableSet');\n\ntype CompilationHooksJavascriptModulesPlugin = ReturnType<\n typeof javascript.JavascriptModulesPlugin.getCompilationHooks\n>;\ntype RenderStartup = CompilationHooksJavascriptModulesPlugin['renderStartup'];\n\ntype InferStartupRenderContext<T> =\n T extends SyncWaterfallHook<\n [infer Source, infer Module, infer StartupRenderContext]\n >\n ? StartupRenderContext\n : never;\n\ntype StartupRenderContext = InferStartupRenderContext<RenderStartup>;\n\nexport interface Options {\n eager?: RegExp | ((module: Module) => boolean);\n excludeChunk?: (chunk: Chunk) => boolean;\n}\n\nclass EntryChunkTrackerPlugin {\n private _options: Options;\n\n constructor(options?: Options) {\n this._options = options || {};\n }\n\n apply(compiler: Compiler) {\n compiler.hooks.thisCompilation.tap(\n 'EntryChunkTrackerPlugin',\n (compilation: Compilation) => {\n this._handleRenderStartup(compiler, compilation);\n },\n );\n }\n private _handleRenderStartup(compiler: Compiler, compilation: Compilation) {\n compiler.webpack.javascript.JavascriptModulesPlugin.getCompilationHooks(\n compilation,\n ).renderStartup.tap(\n 'EntryChunkTrackerPlugin',\n (\n source: sources.Source,\n _renderContext: Module,\n upperContext: StartupRenderContext,\n ) => {\n if (\n this._options.excludeChunk &&\n this._options.excludeChunk(upperContext.chunk)\n ) {\n return source;\n }\n\n const templateString = this._getTemplateString(compiler, source);\n\n return new compiler.webpack.sources.ConcatSource(templateString);\n },\n );\n }\n\n private _getTemplateString(compiler: Compiler, source: sources.Source) {\n const { Template } = compiler.webpack;\n return Template.asString([\n `if(typeof module !== 'undefined') {\n globalThis.entryChunkCache = globalThis.entryChunkCache || new Set();\n module.filename && globalThis.entryChunkCache.add(module.filename);\n if(module.children) {\n module.children.forEach(function(c) {\n c.filename && globalThis.entryChunkCache.add(c.filename);\n })\n}\n }`,\n Template.indent(source.source().toString()),\n ]);\n }\n}\n\nexport default EntryChunkTrackerPlugin;\n"],"mappings":";;;;;AAYoB,gFACG,+BAA+B,CACrD;AAqBD,IAAM,0BAAN,MAA8B;CAG5B,YAAY,SAAmB;AAC7B,OAAK,WAAW,WAAW,EAAE;;CAG/B,MAAM,UAAoB;AACxB,WAAS,MAAM,gBAAgB,IAC7B,4BACC,gBAA6B;AAC5B,QAAK,qBAAqB,UAAU,YAAY;IAEnD;;CAEH,AAAQ,qBAAqB,UAAoB,aAA0B;AACzE,WAAS,QAAQ,WAAW,wBAAwB,oBAClD,YACD,CAAC,cAAc,IACd,4BAEE,QACA,gBACA,iBACG;AACH,OACE,KAAK,SAAS,gBACd,KAAK,SAAS,aAAa,aAAa,MAAM,CAE9C,QAAO;GAGT,MAAM,iBAAiB,KAAK,mBAAmB,UAAU,OAAO;AAEhE,UAAO,IAAI,SAAS,QAAQ,QAAQ,aAAa,eAAe;IAEnE;;CAGH,AAAQ,mBAAmB,UAAoB,QAAwB;EACrE,MAAM,EAAE,aAAa,SAAS;AAC9B,SAAO,SAAS,SAAS,CACvB;;;;;;;;UASA,SAAS,OAAO,OAAO,QAAQ,CAAC,UAAU,CAAC,CAC5C,CAAC"}

View File

@@ -0,0 +1,38 @@
import { __require } from "../../_virtual/_rolldown/runtime.mjs";
import { normalizeWebpackPath } from "@module-federation/sdk/normalize-webpack-path";
//#region src/plugins/EntryChunkTrackerPlugin.ts
__require(normalizeWebpackPath("webpack/lib/util/SortableSet"));
var EntryChunkTrackerPlugin = class {
constructor(options) {
this._options = options || {};
}
apply(compiler) {
compiler.hooks.thisCompilation.tap("EntryChunkTrackerPlugin", (compilation) => {
this._handleRenderStartup(compiler, compilation);
});
}
_handleRenderStartup(compiler, compilation) {
compiler.webpack.javascript.JavascriptModulesPlugin.getCompilationHooks(compilation).renderStartup.tap("EntryChunkTrackerPlugin", (source, _renderContext, upperContext) => {
if (this._options.excludeChunk && this._options.excludeChunk(upperContext.chunk)) return source;
const templateString = this._getTemplateString(compiler, source);
return new compiler.webpack.sources.ConcatSource(templateString);
});
}
_getTemplateString(compiler, source) {
const { Template } = compiler.webpack;
return Template.asString([`if(typeof module !== 'undefined') {
globalThis.entryChunkCache = globalThis.entryChunkCache || new Set();
module.filename && globalThis.entryChunkCache.add(module.filename);
if(module.children) {
module.children.forEach(function(c) {
c.filename && globalThis.entryChunkCache.add(c.filename);
})
}
}`, Template.indent(source.source().toString())]);
}
};
//#endregion
export { EntryChunkTrackerPlugin as default };
//# sourceMappingURL=EntryChunkTrackerPlugin.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"EntryChunkTrackerPlugin.mjs","names":[],"sources":["../../../src/plugins/EntryChunkTrackerPlugin.ts"],"sourcesContent":["import { normalizeWebpackPath } from '@module-federation/sdk/normalize-webpack-path';\nimport type {\n Compiler,\n Compilation,\n Chunk,\n sources,\n Module,\n RuntimeGlobals,\n javascript,\n} from 'webpack';\nimport type { SyncWaterfallHook } from 'tapable';\n\nconst SortableSet = require(\n normalizeWebpackPath('webpack/lib/util/SortableSet'),\n) as typeof import('webpack/lib/util/SortableSet');\n\ntype CompilationHooksJavascriptModulesPlugin = ReturnType<\n typeof javascript.JavascriptModulesPlugin.getCompilationHooks\n>;\ntype RenderStartup = CompilationHooksJavascriptModulesPlugin['renderStartup'];\n\ntype InferStartupRenderContext<T> =\n T extends SyncWaterfallHook<\n [infer Source, infer Module, infer StartupRenderContext]\n >\n ? StartupRenderContext\n : never;\n\ntype StartupRenderContext = InferStartupRenderContext<RenderStartup>;\n\nexport interface Options {\n eager?: RegExp | ((module: Module) => boolean);\n excludeChunk?: (chunk: Chunk) => boolean;\n}\n\nclass EntryChunkTrackerPlugin {\n private _options: Options;\n\n constructor(options?: Options) {\n this._options = options || {};\n }\n\n apply(compiler: Compiler) {\n compiler.hooks.thisCompilation.tap(\n 'EntryChunkTrackerPlugin',\n (compilation: Compilation) => {\n this._handleRenderStartup(compiler, compilation);\n },\n );\n }\n private _handleRenderStartup(compiler: Compiler, compilation: Compilation) {\n compiler.webpack.javascript.JavascriptModulesPlugin.getCompilationHooks(\n compilation,\n ).renderStartup.tap(\n 'EntryChunkTrackerPlugin',\n (\n source: sources.Source,\n _renderContext: Module,\n upperContext: StartupRenderContext,\n ) => {\n if (\n this._options.excludeChunk &&\n this._options.excludeChunk(upperContext.chunk)\n ) {\n return source;\n }\n\n const templateString = this._getTemplateString(compiler, source);\n\n return new compiler.webpack.sources.ConcatSource(templateString);\n },\n );\n }\n\n private _getTemplateString(compiler: Compiler, source: sources.Source) {\n const { Template } = compiler.webpack;\n return Template.asString([\n `if(typeof module !== 'undefined') {\n globalThis.entryChunkCache = globalThis.entryChunkCache || new Set();\n module.filename && globalThis.entryChunkCache.add(module.filename);\n if(module.children) {\n module.children.forEach(function(c) {\n c.filename && globalThis.entryChunkCache.add(c.filename);\n })\n}\n }`,\n Template.indent(source.source().toString()),\n ]);\n }\n}\n\nexport default EntryChunkTrackerPlugin;\n"],"mappings":";;;;UAaE,qBAAqB,+BAA+B,CACrD;AAqBD,IAAM,0BAAN,MAA8B;CAG5B,YAAY,SAAmB;AAC7B,OAAK,WAAW,WAAW,EAAE;;CAG/B,MAAM,UAAoB;AACxB,WAAS,MAAM,gBAAgB,IAC7B,4BACC,gBAA6B;AAC5B,QAAK,qBAAqB,UAAU,YAAY;IAEnD;;CAEH,AAAQ,qBAAqB,UAAoB,aAA0B;AACzE,WAAS,QAAQ,WAAW,wBAAwB,oBAClD,YACD,CAAC,cAAc,IACd,4BAEE,QACA,gBACA,iBACG;AACH,OACE,KAAK,SAAS,gBACd,KAAK,SAAS,aAAa,aAAa,MAAM,CAE9C,QAAO;GAGT,MAAM,iBAAiB,KAAK,mBAAmB,UAAU,OAAO;AAEhE,UAAO,IAAI,SAAS,QAAQ,QAAQ,aAAa,eAAe;IAEnE;;CAGH,AAAQ,mBAAmB,UAAoB,QAAwB;EACrE,MAAM,EAAE,aAAa,SAAS;AAC9B,SAAO,SAAS,SAAS,CACvB;;;;;;;;UASA,SAAS,OAAO,OAAO,QAAQ,CAAC,UAAU,CAAC,CAC5C,CAAC"}

View File

@@ -0,0 +1,54 @@
import { ModuleFederationPluginOptions } from "../types/index.mjs";
import { Compiler, container } from "webpack";
//#region src/plugins/NodeFederationPlugin.d.ts
/**
* Interface for NodeFederationOptions which extends ModuleFederationPluginOptions
* @interface
* @property {boolean} debug - Optional debug flag
*/
interface NodeFederationOptions extends ModuleFederationPluginOptions {
debug?: boolean;
useRuntimePlugin?: boolean;
}
/**
* Interface for Context
* @interface
* @property {typeof container.ModuleFederationPlugin} ModuleFederationPlugin - Optional ModuleFederationPlugin
*/
interface Context {
ModuleFederationPlugin?: typeof container.ModuleFederationPlugin;
}
/**
* Class representing a NodeFederationPlugin.
* @class
*/
declare class NodeFederationPlugin {
private _options;
private context;
private useRuntimePlugin?;
private logger;
/**
* Create a NodeFederationPlugin.
* @constructor
* @param {NodeFederationOptions} options - The options for the NodeFederationPlugin
* @param {Context} context - The context for the NodeFederationPlugin
*/
constructor({
debug,
useRuntimePlugin,
...options
}: NodeFederationOptions, context: Context);
/**
* Apply method for the NodeFederationPlugin class.
* @method
* @param {Compiler} compiler - The webpack compiler.
*/
apply(compiler: Compiler): void;
private preparePluginOptions;
private updateCompilerOptions;
private getModuleFederationPlugin;
}
//#endregion
export { NodeFederationPlugin as default };
//# sourceMappingURL=NodeFederationPlugin.d.mts.map

View File

@@ -0,0 +1,53 @@
import { ModuleFederationPluginOptions } from "../types/index.js";
import { Compiler, container } from "webpack";
//#region src/plugins/NodeFederationPlugin.d.ts
/**
* Interface for NodeFederationOptions which extends ModuleFederationPluginOptions
* @interface
* @property {boolean} debug - Optional debug flag
*/
interface NodeFederationOptions extends ModuleFederationPluginOptions {
debug?: boolean;
useRuntimePlugin?: boolean;
}
/**
* Interface for Context
* @interface
* @property {typeof container.ModuleFederationPlugin} ModuleFederationPlugin - Optional ModuleFederationPlugin
*/
interface Context {
ModuleFederationPlugin?: typeof container.ModuleFederationPlugin;
}
/**
* Class representing a NodeFederationPlugin.
* @class
*/
declare class NodeFederationPlugin {
private _options;
private context;
private useRuntimePlugin?;
private logger;
/**
* Create a NodeFederationPlugin.
* @constructor
* @param {NodeFederationOptions} options - The options for the NodeFederationPlugin
* @param {Context} context - The context for the NodeFederationPlugin
*/
constructor({
debug,
useRuntimePlugin,
...options
}: NodeFederationOptions, context: Context);
/**
* Apply method for the NodeFederationPlugin class.
* @method
* @param {Compiler} compiler - The webpack compiler.
*/
apply(compiler: Compiler): void;
private preparePluginOptions;
private updateCompilerOptions;
private getModuleFederationPlugin;
}
export = NodeFederationPlugin;
//# sourceMappingURL=NodeFederationPlugin.d.ts.map

View File

@@ -0,0 +1,76 @@
'use strict';
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
const require_runtime = require('../../_virtual/_rolldown/runtime.js');
const require_src_plugins_EntryChunkTrackerPlugin = require('./EntryChunkTrackerPlugin.js');
let _module_federation_sdk = require("@module-federation/sdk");
//#region src/plugins/NodeFederationPlugin.ts
const createBundlerLogger = typeof _module_federation_sdk.createInfrastructureLogger === "function" ? _module_federation_sdk.createInfrastructureLogger : _module_federation_sdk.createLogger;
function getRuntimePluginPath() {
return require.resolve("../runtimePlugin.js");
}
/**
* Class representing a NodeFederationPlugin.
* @class
*/
var NodeFederationPlugin = class {
/**
* Create a NodeFederationPlugin.
* @constructor
* @param {NodeFederationOptions} options - The options for the NodeFederationPlugin
* @param {Context} context - The context for the NodeFederationPlugin
*/
constructor({ debug, useRuntimePlugin, ...options }, context) {
this.logger = createBundlerLogger("[ Node Federation Plugin ]");
this._options = options || {};
this.context = context || {};
this.useRuntimePlugin = useRuntimePlugin || false;
}
/**
* Apply method for the NodeFederationPlugin class.
* @method
* @param {Compiler} compiler - The webpack compiler.
*/
apply(compiler) {
(0, _module_federation_sdk.bindLoggerToCompiler)(this.logger, compiler, "NodeFederationPlugin");
const { webpack } = compiler;
const pluginOptions = this.preparePluginOptions();
this.updateCompilerOptions(compiler);
new (this.getModuleFederationPlugin(compiler, webpack))(pluginOptions).apply(compiler);
new require_src_plugins_EntryChunkTrackerPlugin.default({}).apply(compiler);
}
preparePluginOptions() {
this._options.runtimePlugins = [...this.useRuntimePlugin ? [getRuntimePluginPath()] : [], ...this._options.runtimePlugins || []];
return {
...this._options,
remotes: this._options.remotes || {},
runtimePlugins: this._options.runtimePlugins,
dts: this._options.dts ?? false
};
}
updateCompilerOptions(compiler) {
const chunkFileName = compiler.options?.output?.chunkFilename;
const uniqueName = compiler?.options?.output?.uniqueName || this._options.name;
if (typeof chunkFileName === "string" && uniqueName && !chunkFileName.includes(uniqueName)) {
const suffix = `-[contenthash].js`;
compiler.options.output.chunkFilename = chunkFileName.replace(".js", suffix);
}
}
getModuleFederationPlugin(compiler, webpack) {
let ModuleFederationPlugin;
try {
return require("@module-federation/enhanced").ModuleFederationPlugin;
} catch (e) {
this.logger.error("Can't find @module-federation/enhanced, falling back to webpack ModuleFederationPlugin, this may not work");
if (this.context.ModuleFederationPlugin) ModuleFederationPlugin = this.context.ModuleFederationPlugin;
else if (webpack && webpack.container && webpack.container.ModuleFederationPlugin) ModuleFederationPlugin = webpack.container.ModuleFederationPlugin;
else ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
return ModuleFederationPlugin;
}
}
};
//#endregion
exports.default = NodeFederationPlugin;
//# sourceMappingURL=NodeFederationPlugin.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,73 @@
import { __require } from "../../_virtual/_rolldown/runtime.mjs";
import EntryChunkTrackerPlugin from "./EntryChunkTrackerPlugin.mjs";
import { bindLoggerToCompiler, createInfrastructureLogger, createLogger } from "@module-federation/sdk";
//#region src/plugins/NodeFederationPlugin.ts
const createBundlerLogger = typeof createInfrastructureLogger === "function" ? createInfrastructureLogger : createLogger;
function getRuntimePluginPath() {
return __require.resolve("../runtimePlugin.mjs");
}
/**
* Class representing a NodeFederationPlugin.
* @class
*/
var NodeFederationPlugin = class {
/**
* Create a NodeFederationPlugin.
* @constructor
* @param {NodeFederationOptions} options - The options for the NodeFederationPlugin
* @param {Context} context - The context for the NodeFederationPlugin
*/
constructor({ debug, useRuntimePlugin, ...options }, context) {
this.logger = createBundlerLogger("[ Node Federation Plugin ]");
this._options = options || {};
this.context = context || {};
this.useRuntimePlugin = useRuntimePlugin || false;
}
/**
* Apply method for the NodeFederationPlugin class.
* @method
* @param {Compiler} compiler - The webpack compiler.
*/
apply(compiler) {
bindLoggerToCompiler(this.logger, compiler, "NodeFederationPlugin");
const { webpack } = compiler;
const pluginOptions = this.preparePluginOptions();
this.updateCompilerOptions(compiler);
new (this.getModuleFederationPlugin(compiler, webpack))(pluginOptions).apply(compiler);
new EntryChunkTrackerPlugin({}).apply(compiler);
}
preparePluginOptions() {
this._options.runtimePlugins = [...this.useRuntimePlugin ? [getRuntimePluginPath()] : [], ...this._options.runtimePlugins || []];
return {
...this._options,
remotes: this._options.remotes || {},
runtimePlugins: this._options.runtimePlugins,
dts: this._options.dts ?? false
};
}
updateCompilerOptions(compiler) {
const chunkFileName = compiler.options?.output?.chunkFilename;
const uniqueName = compiler?.options?.output?.uniqueName || this._options.name;
if (typeof chunkFileName === "string" && uniqueName && !chunkFileName.includes(uniqueName)) {
const suffix = `-[contenthash].js`;
compiler.options.output.chunkFilename = chunkFileName.replace(".js", suffix);
}
}
getModuleFederationPlugin(compiler, webpack) {
let ModuleFederationPlugin;
try {
return __require("@module-federation/enhanced").ModuleFederationPlugin;
} catch (e) {
this.logger.error("Can't find @module-federation/enhanced, falling back to webpack ModuleFederationPlugin, this may not work");
if (this.context.ModuleFederationPlugin) ModuleFederationPlugin = this.context.ModuleFederationPlugin;
else if (webpack && webpack.container && webpack.container.ModuleFederationPlugin) ModuleFederationPlugin = webpack.container.ModuleFederationPlugin;
else ModuleFederationPlugin = __require("webpack/lib/container/ModuleFederationPlugin");
return ModuleFederationPlugin;
}
}
};
//#endregion
export { NodeFederationPlugin as default };
//# sourceMappingURL=NodeFederationPlugin.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,15 @@
import * as webpack from "webpack";
//#region src/plugins/RemotePublicPathRuntimeModule.d.ts
declare const RuntimeModule: typeof webpack.RuntimeModule;
declare class AutoPublicPathRuntimeModule extends RuntimeModule {
private options;
constructor(options: any);
/**
* @returns {string} runtime code
*/
generate(): string;
}
//#endregion
export { AutoPublicPathRuntimeModule as default };
//# sourceMappingURL=RemotePublicPathRuntimeModule.d.mts.map

View File

@@ -0,0 +1,14 @@
import * as webpack from "webpack";
//#region src/plugins/RemotePublicPathRuntimeModule.d.ts
declare const RuntimeModule: typeof webpack.RuntimeModule;
declare class AutoPublicPathRuntimeModule extends RuntimeModule {
private options;
constructor(options: any);
/**
* @returns {string} runtime code
*/
generate(): string;
}
export = AutoPublicPathRuntimeModule;
//# sourceMappingURL=RemotePublicPathRuntimeModule.d.ts.map

View File

@@ -0,0 +1,133 @@
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
const require_runtime = require('../../_virtual/_rolldown/runtime.js');
let _module_federation_sdk_normalize_webpack_path = require("@module-federation/sdk/normalize-webpack-path");
//#region src/plugins/RemotePublicPathRuntimeModule.ts
const { RuntimeGlobals, RuntimeModule, Template, javascript } = require((0, _module_federation_sdk_normalize_webpack_path.normalizeWebpackPath)("webpack"));
const { getUndoPath } = require((0, _module_federation_sdk_normalize_webpack_path.normalizeWebpackPath)("webpack/lib/util/identifier"));
var AutoPublicPathRuntimeModule = class extends RuntimeModule {
constructor(options) {
super("publicPath", RuntimeModule.STAGE_BASIC + 1);
this.options = options;
}
/**
* @returns {string} runtime code
*/
generate() {
const { compilation } = this;
const { scriptType, path, publicPath, importMetaName, uniqueName, chunkLoading } = compilation.outputOptions;
const getPath = () => compilation?.getPath(publicPath || "", { hash: compilation?.hash || "XXXX" });
const currentChunk = this.chunk;
const chunkName = currentChunk && compilation?.getPath(javascript.JavascriptModulesPlugin.getChunkFilenameTemplate(currentChunk, compilation?.outputOptions), {
chunk: currentChunk,
contentHashType: "javascript"
});
let undoPath = null;
if (chunkName && path) undoPath = getUndoPath(chunkName, path, false);
const getPathFromFederation = `
function getPathFromFederation() {
// Access the global federation manager or create a fallback object
var federationManager = globalThis.__FEDERATION__ || {};
// Access the current Webpack instance's federation details or create a fallback object
var instance = __webpack_require__.federation.instance || {};
// Function to aggregate all known remote module paths
var getAllKnownRemotes = function() {
var found = {};
// Iterate over all federation instances to collect module cache entries
(federationManager.__INSTANCES__ || []).forEach((instance) => {
if(instance){
instance.moduleCache.forEach((value, key) => {
found[key] = value;
});
}
});
return found;
};
// Retrieve the combined remote cache from all federation instances
const combinedRemoteCache = getAllKnownRemotes();
// Get the name of the current host from the instance
const hostName = instance.name;
// Find the path for the current host in the remote cache
const foundPath = combinedRemoteCache[hostName];
// If a path is not found, return undefined to indicate the absence of an entry path
if (!foundPath) { return undefined; }
// Return the entry path for the found remote module
const entryPath = foundPath.remoteInfo.entry;
return entryPath;
}
`;
const definePropertyCode = `
Object.defineProperty(__webpack_require__, "p", {
get: function() {
var scriptUrl;
// Attempt to get the script URL based on the environment
var scriptType = ${JSON.stringify(scriptType)};
var chunkLoading = ${JSON.stringify(chunkLoading)};
var isModuleEnvironment = ['module', 'node', 'async-node', 'require'].includes(scriptType) || chunkLoading;
if (isModuleEnvironment) {
try {
// Use Function constructor to avoid direct reference to import.meta in environments that do not support it
scriptUrl = (new Function('return typeof ${importMetaName}.url === "string" ? ${importMetaName}.url : undefined;'))();
} catch (e) {
// Handle cases where import.meta is not available or other errors occur
var scriptPath = getPathFromFederation();
if (scriptPath) {
scriptUrl = scriptPath;
} else if (typeof __filename !== "undefined") {
scriptUrl = __filename;
} else {
scriptUrl = ${publicPath !== "auto" ? JSON.stringify(getPath()) : "undefined"};
}
}
} else {
// Fallback for non-module environments, such as browsers
if (${RuntimeGlobals.global}.importScripts) {
scriptUrl = ${RuntimeGlobals.global}.location + "";
}
var document = ${RuntimeGlobals.global}.document;
if (!scriptUrl && document) {
if (document.currentScript) {
scriptUrl = document.currentScript.src;
} else {
var scripts = document.getElementsByTagName("script");
if (scripts.length) {
scriptUrl = scripts[scripts.length - 1].src;
}
}
}
}
if (!scriptUrl) {
throw new Error("Unable to calculate automatic public path");
}
// Clean up the script URL by removing any hash or query parameters
scriptUrl = scriptUrl.replace(/#.*$/, "").replace(/\\?.*$/, "").replace(/\\/[^\\/]+$/, "/");
// Apply any undo path that might be necessary for nested public paths
var finalScript = ${JSON.stringify(undoPath)} ? scriptUrl + ${JSON.stringify(undoPath)} : scriptUrl;
// Helper function to ensure the URL has a protocol if it starts with '//'
var addProtocol = function(url) {
return url.startsWith('//') ? 'https:' + url : url;
};
// Set the global variable for the public path
globalThis.currentVmokPublicPath = addProtocol(finalScript) || '/';
// Return the final public path
return finalScript
}
});
`;
return Template.asString([getPathFromFederation, definePropertyCode]);
}
};
//#endregion
exports.default = AutoPublicPathRuntimeModule;
//# sourceMappingURL=RemotePublicPathRuntimeModule.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,132 @@
import { __require } from "../../_virtual/_rolldown/runtime.mjs";
import { normalizeWebpackPath } from "@module-federation/sdk/normalize-webpack-path";
//#region src/plugins/RemotePublicPathRuntimeModule.ts
const { RuntimeGlobals, RuntimeModule, Template, javascript } = __require(normalizeWebpackPath("webpack"));
const { getUndoPath } = __require(normalizeWebpackPath("webpack/lib/util/identifier"));
var AutoPublicPathRuntimeModule = class extends RuntimeModule {
constructor(options) {
super("publicPath", RuntimeModule.STAGE_BASIC + 1);
this.options = options;
}
/**
* @returns {string} runtime code
*/
generate() {
const { compilation } = this;
const { scriptType, path, publicPath, importMetaName, uniqueName, chunkLoading } = compilation.outputOptions;
const getPath = () => compilation?.getPath(publicPath || "", { hash: compilation?.hash || "XXXX" });
const currentChunk = this.chunk;
const chunkName = currentChunk && compilation?.getPath(javascript.JavascriptModulesPlugin.getChunkFilenameTemplate(currentChunk, compilation?.outputOptions), {
chunk: currentChunk,
contentHashType: "javascript"
});
let undoPath = null;
if (chunkName && path) undoPath = getUndoPath(chunkName, path, false);
const getPathFromFederation = `
function getPathFromFederation() {
// Access the global federation manager or create a fallback object
var federationManager = globalThis.__FEDERATION__ || {};
// Access the current Webpack instance's federation details or create a fallback object
var instance = __webpack_require__.federation.instance || {};
// Function to aggregate all known remote module paths
var getAllKnownRemotes = function() {
var found = {};
// Iterate over all federation instances to collect module cache entries
(federationManager.__INSTANCES__ || []).forEach((instance) => {
if(instance){
instance.moduleCache.forEach((value, key) => {
found[key] = value;
});
}
});
return found;
};
// Retrieve the combined remote cache from all federation instances
const combinedRemoteCache = getAllKnownRemotes();
// Get the name of the current host from the instance
const hostName = instance.name;
// Find the path for the current host in the remote cache
const foundPath = combinedRemoteCache[hostName];
// If a path is not found, return undefined to indicate the absence of an entry path
if (!foundPath) { return undefined; }
// Return the entry path for the found remote module
const entryPath = foundPath.remoteInfo.entry;
return entryPath;
}
`;
const definePropertyCode = `
Object.defineProperty(__webpack_require__, "p", {
get: function() {
var scriptUrl;
// Attempt to get the script URL based on the environment
var scriptType = ${JSON.stringify(scriptType)};
var chunkLoading = ${JSON.stringify(chunkLoading)};
var isModuleEnvironment = ['module', 'node', 'async-node', 'require'].includes(scriptType) || chunkLoading;
if (isModuleEnvironment) {
try {
// Use Function constructor to avoid direct reference to import.meta in environments that do not support it
scriptUrl = (new Function('return typeof ${importMetaName}.url === "string" ? ${importMetaName}.url : undefined;'))();
} catch (e) {
// Handle cases where import.meta is not available or other errors occur
var scriptPath = getPathFromFederation();
if (scriptPath) {
scriptUrl = scriptPath;
} else if (typeof __filename !== "undefined") {
scriptUrl = __filename;
} else {
scriptUrl = ${publicPath !== "auto" ? JSON.stringify(getPath()) : "undefined"};
}
}
} else {
// Fallback for non-module environments, such as browsers
if (${RuntimeGlobals.global}.importScripts) {
scriptUrl = ${RuntimeGlobals.global}.location + "";
}
var document = ${RuntimeGlobals.global}.document;
if (!scriptUrl && document) {
if (document.currentScript) {
scriptUrl = document.currentScript.src;
} else {
var scripts = document.getElementsByTagName("script");
if (scripts.length) {
scriptUrl = scripts[scripts.length - 1].src;
}
}
}
}
if (!scriptUrl) {
throw new Error("Unable to calculate automatic public path");
}
// Clean up the script URL by removing any hash or query parameters
scriptUrl = scriptUrl.replace(/#.*$/, "").replace(/\\?.*$/, "").replace(/\\/[^\\/]+$/, "/");
// Apply any undo path that might be necessary for nested public paths
var finalScript = ${JSON.stringify(undoPath)} ? scriptUrl + ${JSON.stringify(undoPath)} : scriptUrl;
// Helper function to ensure the URL has a protocol if it starts with '//'
var addProtocol = function(url) {
return url.startsWith('//') ? 'https:' + url : url;
};
// Set the global variable for the public path
globalThis.currentVmokPublicPath = addProtocol(finalScript) || '/';
// Return the final public path
return finalScript
}
});
`;
return Template.asString([getPathFromFederation, definePropertyCode]);
}
};
//#endregion
export { AutoPublicPathRuntimeModule as default };
//# sourceMappingURL=RemotePublicPathRuntimeModule.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,32 @@
import { ModuleFederationPluginOptions } from "../types/index.mjs";
import { Compiler, WebpackPluginInstance } from "webpack";
//#region src/plugins/StreamingTargetPlugin.d.ts
/**
* Interface for StreamingTargetOptions which extends ModuleFederationPluginOptions
* @property {string} promiseBaseURI - The base URI for the promise
* @property {boolean} debug - Flag to enable/disable debug mode
*/
interface StreamingTargetOptions extends ModuleFederationPluginOptions {
promiseBaseURI?: string;
debug?: boolean;
}
/**
* Class representing a StreamingTargetPlugin
*/
declare class StreamingTargetPlugin implements WebpackPluginInstance {
private options;
/**
* Create a StreamingTargetPlugin
* @param {StreamingTargetOptions} options - The options for the plugin
*/
constructor(options: StreamingTargetOptions);
/**
* Apply the plugin to the compiler
* @param {Compiler} compiler - The webpack compiler
*/
apply(compiler: Compiler): void;
}
//#endregion
export { StreamingTargetPlugin as default };
//# sourceMappingURL=StreamingTargetPlugin.d.mts.map

View File

@@ -0,0 +1,31 @@
import { ModuleFederationPluginOptions } from "../types/index.js";
import { Compiler, WebpackPluginInstance } from "webpack";
//#region src/plugins/StreamingTargetPlugin.d.ts
/**
* Interface for StreamingTargetOptions which extends ModuleFederationPluginOptions
* @property {string} promiseBaseURI - The base URI for the promise
* @property {boolean} debug - Flag to enable/disable debug mode
*/
interface StreamingTargetOptions extends ModuleFederationPluginOptions {
promiseBaseURI?: string;
debug?: boolean;
}
/**
* Class representing a StreamingTargetPlugin
*/
declare class StreamingTargetPlugin implements WebpackPluginInstance {
private options;
/**
* Create a StreamingTargetPlugin
* @param {StreamingTargetOptions} options - The options for the plugin
*/
constructor(options: StreamingTargetOptions);
/**
* Apply the plugin to the compiler
* @param {Compiler} compiler - The webpack compiler
*/
apply(compiler: Compiler): void;
}
export = StreamingTargetPlugin;
//# sourceMappingURL=StreamingTargetPlugin.d.ts.map

View File

@@ -0,0 +1,46 @@
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
const require_src_plugins_CommonJsChunkLoadingPlugin = require('./CommonJsChunkLoadingPlugin.js');
//#region src/plugins/StreamingTargetPlugin.ts
/**
* Class representing a StreamingTargetPlugin
*/
var StreamingTargetPlugin = class {
/**
* Create a StreamingTargetPlugin
* @param {StreamingTargetOptions} options - The options for the plugin
*/
constructor(options) {
this.options = options || {};
}
/**
* Apply the plugin to the compiler
* @param {Compiler} compiler - The webpack compiler
*/
apply(compiler) {
const { webpack } = compiler;
compiler.options.output.chunkFormat = "commonjs";
if (compiler.options.output.enabledLibraryTypes === void 0) compiler.options.output.enabledLibraryTypes = ["commonjs-module"];
else compiler.options.output.enabledLibraryTypes.push("commonjs-module");
compiler.options.output.chunkLoading = "async-node";
compiler.options.output.enabledChunkLoadingTypes = [];
compiler.options.output.environment = {
...compiler.options.output.environment,
dynamicImport: true
};
new (webpack?.node?.NodeEnvironmentPlugin || (require("webpack/lib/node/NodeEnvironmentPlugin")))({ infrastructureLogging: compiler.options.infrastructureLogging }).apply(compiler);
new (webpack?.node?.NodeTargetPlugin || (require("webpack/lib/node/NodeTargetPlugin")))().apply(compiler);
new require_src_plugins_CommonJsChunkLoadingPlugin.default({
asyncChunkLoading: true,
name: this.options.name,
remotes: this.options.remotes,
baseURI: compiler.options.output.publicPath,
promiseBaseURI: this.options.promiseBaseURI,
debug: this.options.debug
}).apply(compiler);
}
};
//#endregion
exports.default = StreamingTargetPlugin;
//# sourceMappingURL=StreamingTargetPlugin.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"StreamingTargetPlugin.js","names":["CommonJsChunkLoadingPlugin"],"sources":["../../../src/plugins/StreamingTargetPlugin.ts"],"sourcesContent":["import type { Compiler, WebpackPluginInstance } from 'webpack';\nimport type { ModuleFederationPluginOptions } from '../types';\n\nimport CommonJsChunkLoadingPlugin from './CommonJsChunkLoadingPlugin';\n\n/**\n * Interface for StreamingTargetOptions which extends ModuleFederationPluginOptions\n * @property {string} promiseBaseURI - The base URI for the promise\n * @property {boolean} debug - Flag to enable/disable debug mode\n */\ninterface StreamingTargetOptions extends ModuleFederationPluginOptions {\n promiseBaseURI?: string;\n debug?: boolean;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\n/**\n * Interface for StreamingTargetContext\n */\ninterface StreamingTargetContext {}\n\n/**\n * Class representing a StreamingTargetPlugin\n */\nclass StreamingTargetPlugin implements WebpackPluginInstance {\n private options: StreamingTargetOptions;\n\n /**\n * Create a StreamingTargetPlugin\n * @param {StreamingTargetOptions} options - The options for the plugin\n */\n constructor(options: StreamingTargetOptions) {\n this.options = options || {};\n }\n\n /**\n * Apply the plugin to the compiler\n * @param {Compiler} compiler - The webpack compiler\n */\n apply(compiler: Compiler) {\n // When used with Next.js, context is needed to use Next.js webpack\n const { webpack } = compiler;\n\n compiler.options.output.chunkFormat = 'commonjs';\n if (compiler.options.output.enabledLibraryTypes === undefined) {\n compiler.options.output.enabledLibraryTypes = ['commonjs-module'];\n } else {\n compiler.options.output.enabledLibraryTypes.push('commonjs-module');\n }\n\n compiler.options.output.chunkLoading = 'async-node';\n\n // Disable default config\n // FIXME: enabledChunkLoadingTypes is of type 'string[] | undefined'\n // Can't use the 'false' value as it isn't the right format,\n // Emptying it out ensures theres no other readFileVm added to webpack runtime\n compiler.options.output.enabledChunkLoadingTypes = [];\n compiler.options.output.environment = {\n ...compiler.options.output.environment,\n dynamicImport: true,\n };\n\n new (\n webpack?.node?.NodeEnvironmentPlugin ||\n require('webpack/lib/node/NodeEnvironmentPlugin')\n )({\n infrastructureLogging: compiler.options.infrastructureLogging,\n }).apply(compiler);\n\n new (\n webpack?.node?.NodeTargetPlugin ||\n require('webpack/lib/node/NodeTargetPlugin')\n )().apply(compiler);\n new CommonJsChunkLoadingPlugin({\n asyncChunkLoading: true,\n name: this.options.name,\n remotes: this.options.remotes as Record<string, string>,\n baseURI: compiler.options.output.publicPath,\n promiseBaseURI: this.options.promiseBaseURI,\n debug: this.options.debug,\n }).apply(compiler);\n }\n}\n\nexport default StreamingTargetPlugin;\n"],"mappings":";;;;;;;AAwBA,IAAM,wBAAN,MAA6D;;;;;CAO3D,YAAY,SAAiC;AAC3C,OAAK,UAAU,WAAW,EAAE;;;;;;CAO9B,MAAM,UAAoB;EAExB,MAAM,EAAE,YAAY;AAEpB,WAAS,QAAQ,OAAO,cAAc;AACtC,MAAI,SAAS,QAAQ,OAAO,wBAAwB,OAClD,UAAS,QAAQ,OAAO,sBAAsB,CAAC,kBAAkB;MAEjE,UAAS,QAAQ,OAAO,oBAAoB,KAAK,kBAAkB;AAGrE,WAAS,QAAQ,OAAO,eAAe;AAMvC,WAAS,QAAQ,OAAO,2BAA2B,EAAE;AACrD,WAAS,QAAQ,OAAO,cAAc;GACpC,GAAG,SAAS,QAAQ,OAAO;GAC3B,eAAe;GAChB;AAED,OACE,SAAS,MAAM,0BACf,QAAQ,yCAAyC,GACjD,EACA,uBAAuB,SAAS,QAAQ,uBACzC,CAAC,CAAC,MAAM,SAAS;AAElB,OACE,SAAS,MAAM,qBACf,QAAQ,oCAAoC,IAC3C,CAAC,MAAM,SAAS;AACnB,MAAIA,uDAA2B;GAC7B,mBAAmB;GACnB,MAAM,KAAK,QAAQ;GACnB,SAAS,KAAK,QAAQ;GACtB,SAAS,SAAS,QAAQ,OAAO;GACjC,gBAAgB,KAAK,QAAQ;GAC7B,OAAO,KAAK,QAAQ;GACrB,CAAC,CAAC,MAAM,SAAS"}

View File

@@ -0,0 +1,46 @@
import { __require } from "../../_virtual/_rolldown/runtime.mjs";
import DynamicFilesystemChunkLoadingPlugin from "./CommonJsChunkLoadingPlugin.mjs";
//#region src/plugins/StreamingTargetPlugin.ts
/**
* Class representing a StreamingTargetPlugin
*/
var StreamingTargetPlugin = class {
/**
* Create a StreamingTargetPlugin
* @param {StreamingTargetOptions} options - The options for the plugin
*/
constructor(options) {
this.options = options || {};
}
/**
* Apply the plugin to the compiler
* @param {Compiler} compiler - The webpack compiler
*/
apply(compiler) {
const { webpack } = compiler;
compiler.options.output.chunkFormat = "commonjs";
if (compiler.options.output.enabledLibraryTypes === void 0) compiler.options.output.enabledLibraryTypes = ["commonjs-module"];
else compiler.options.output.enabledLibraryTypes.push("commonjs-module");
compiler.options.output.chunkLoading = "async-node";
compiler.options.output.enabledChunkLoadingTypes = [];
compiler.options.output.environment = {
...compiler.options.output.environment,
dynamicImport: true
};
new (webpack?.node?.NodeEnvironmentPlugin || (__require("webpack/lib/node/NodeEnvironmentPlugin")))({ infrastructureLogging: compiler.options.infrastructureLogging }).apply(compiler);
new (webpack?.node?.NodeTargetPlugin || (__require("webpack/lib/node/NodeTargetPlugin")))().apply(compiler);
new DynamicFilesystemChunkLoadingPlugin({
asyncChunkLoading: true,
name: this.options.name,
remotes: this.options.remotes,
baseURI: compiler.options.output.publicPath,
promiseBaseURI: this.options.promiseBaseURI,
debug: this.options.debug
}).apply(compiler);
}
};
//#endregion
export { StreamingTargetPlugin as default };
//# sourceMappingURL=StreamingTargetPlugin.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"StreamingTargetPlugin.mjs","names":["CommonJsChunkLoadingPlugin"],"sources":["../../../src/plugins/StreamingTargetPlugin.ts"],"sourcesContent":["import type { Compiler, WebpackPluginInstance } from 'webpack';\nimport type { ModuleFederationPluginOptions } from '../types';\n\nimport CommonJsChunkLoadingPlugin from './CommonJsChunkLoadingPlugin';\n\n/**\n * Interface for StreamingTargetOptions which extends ModuleFederationPluginOptions\n * @property {string} promiseBaseURI - The base URI for the promise\n * @property {boolean} debug - Flag to enable/disable debug mode\n */\ninterface StreamingTargetOptions extends ModuleFederationPluginOptions {\n promiseBaseURI?: string;\n debug?: boolean;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\n/**\n * Interface for StreamingTargetContext\n */\ninterface StreamingTargetContext {}\n\n/**\n * Class representing a StreamingTargetPlugin\n */\nclass StreamingTargetPlugin implements WebpackPluginInstance {\n private options: StreamingTargetOptions;\n\n /**\n * Create a StreamingTargetPlugin\n * @param {StreamingTargetOptions} options - The options for the plugin\n */\n constructor(options: StreamingTargetOptions) {\n this.options = options || {};\n }\n\n /**\n * Apply the plugin to the compiler\n * @param {Compiler} compiler - The webpack compiler\n */\n apply(compiler: Compiler) {\n // When used with Next.js, context is needed to use Next.js webpack\n const { webpack } = compiler;\n\n compiler.options.output.chunkFormat = 'commonjs';\n if (compiler.options.output.enabledLibraryTypes === undefined) {\n compiler.options.output.enabledLibraryTypes = ['commonjs-module'];\n } else {\n compiler.options.output.enabledLibraryTypes.push('commonjs-module');\n }\n\n compiler.options.output.chunkLoading = 'async-node';\n\n // Disable default config\n // FIXME: enabledChunkLoadingTypes is of type 'string[] | undefined'\n // Can't use the 'false' value as it isn't the right format,\n // Emptying it out ensures theres no other readFileVm added to webpack runtime\n compiler.options.output.enabledChunkLoadingTypes = [];\n compiler.options.output.environment = {\n ...compiler.options.output.environment,\n dynamicImport: true,\n };\n\n new (\n webpack?.node?.NodeEnvironmentPlugin ||\n require('webpack/lib/node/NodeEnvironmentPlugin')\n )({\n infrastructureLogging: compiler.options.infrastructureLogging,\n }).apply(compiler);\n\n new (\n webpack?.node?.NodeTargetPlugin ||\n require('webpack/lib/node/NodeTargetPlugin')\n )().apply(compiler);\n new CommonJsChunkLoadingPlugin({\n asyncChunkLoading: true,\n name: this.options.name,\n remotes: this.options.remotes as Record<string, string>,\n baseURI: compiler.options.output.publicPath,\n promiseBaseURI: this.options.promiseBaseURI,\n debug: this.options.debug,\n }).apply(compiler);\n }\n}\n\nexport default StreamingTargetPlugin;\n"],"mappings":";;;;;;;AAwBA,IAAM,wBAAN,MAA6D;;;;;CAO3D,YAAY,SAAiC;AAC3C,OAAK,UAAU,WAAW,EAAE;;;;;;CAO9B,MAAM,UAAoB;EAExB,MAAM,EAAE,YAAY;AAEpB,WAAS,QAAQ,OAAO,cAAc;AACtC,MAAI,SAAS,QAAQ,OAAO,wBAAwB,OAClD,UAAS,QAAQ,OAAO,sBAAsB,CAAC,kBAAkB;MAEjE,UAAS,QAAQ,OAAO,oBAAoB,KAAK,kBAAkB;AAGrE,WAAS,QAAQ,OAAO,eAAe;AAMvC,WAAS,QAAQ,OAAO,2BAA2B,EAAE;AACrD,WAAS,QAAQ,OAAO,cAAc;GACpC,GAAG,SAAS,QAAQ,OAAO;GAC3B,eAAe;GAChB;AAED,OACE,SAAS,MAAM,oCACP,yCAAyC,GACjD,EACA,uBAAuB,SAAS,QAAQ,uBACzC,CAAC,CAAC,MAAM,SAAS;AAElB,OACE,SAAS,MAAM,+BACP,oCAAoC,IAC3C,CAAC,MAAM,SAAS;AACnB,MAAIA,oCAA2B;GAC7B,mBAAmB;GACnB,MAAM,KAAK,QAAQ;GACnB,SAAS,KAAK,QAAQ;GACtB,SAAS,SAAS,QAAQ,OAAO;GACjC,gBAAgB,KAAK,QAAQ;GAC7B,OAAO,KAAK,QAAQ;GACrB,CAAC,CAAC,MAAM,SAAS"}

View File

@@ -0,0 +1,49 @@
import { ModuleFederationPluginOptions } from "../types/index.mjs";
import { Compiler, container } from "webpack";
//#region src/plugins/UniversalFederationPlugin.d.ts
/**
* Interface for NodeFederationOptions
* @property {boolean} isServer - Indicates if the server is running
* @property {string} [promiseBaseURI] - The base URI for the promise
* @property {boolean} [debug] - Indicates if debug mode is enabled
*/
interface NodeFederationOptions extends ModuleFederationPluginOptions {
isServer: boolean;
promiseBaseURI?: string;
debug?: boolean;
useRuntimePlugin?: boolean;
}
/**
* Interface for NodeFederationContext
* @property {typeof container.ModuleFederationPlugin} [ModuleFederationPlugin] - The ModuleFederationPlugin from webpack container
*/
interface NodeFederationContext {
ModuleFederationPlugin?: typeof container.ModuleFederationPlugin;
}
/**
* Class representing a UniversalFederationPlugin
*/
declare class UniversalFederationPlugin {
private _options;
private context;
private name;
/**
* Create a UniversalFederationPlugin
* @param {NodeFederationOptions} options - The options for the plugin
* @param {NodeFederationContext} context - The context for the plugin
*/
constructor(options: NodeFederationOptions, context: NodeFederationContext);
private updateCompilerOptions;
/**
* Apply the plugin to the compiler
* @param {Compiler} compiler - The webpack compiler
*/
apply(compiler: Compiler): void;
}
/**
* Exporting UniversalFederationPlugin as default
*/
//#endregion
export { UniversalFederationPlugin as default };
//# sourceMappingURL=UniversalFederationPlugin.d.mts.map

View File

@@ -0,0 +1,48 @@
import { ModuleFederationPluginOptions } from "../types/index.js";
import { Compiler, container } from "webpack";
//#region src/plugins/UniversalFederationPlugin.d.ts
/**
* Interface for NodeFederationOptions
* @property {boolean} isServer - Indicates if the server is running
* @property {string} [promiseBaseURI] - The base URI for the promise
* @property {boolean} [debug] - Indicates if debug mode is enabled
*/
interface NodeFederationOptions extends ModuleFederationPluginOptions {
isServer: boolean;
promiseBaseURI?: string;
debug?: boolean;
useRuntimePlugin?: boolean;
}
/**
* Interface for NodeFederationContext
* @property {typeof container.ModuleFederationPlugin} [ModuleFederationPlugin] - The ModuleFederationPlugin from webpack container
*/
interface NodeFederationContext {
ModuleFederationPlugin?: typeof container.ModuleFederationPlugin;
}
/**
* Class representing a UniversalFederationPlugin
*/
declare class UniversalFederationPlugin {
private _options;
private context;
private name;
/**
* Create a UniversalFederationPlugin
* @param {NodeFederationOptions} options - The options for the plugin
* @param {NodeFederationContext} context - The context for the plugin
*/
constructor(options: NodeFederationOptions, context: NodeFederationContext);
private updateCompilerOptions;
/**
* Apply the plugin to the compiler
* @param {Compiler} compiler - The webpack compiler
*/
apply(compiler: Compiler): void;
}
/**
* Exporting UniversalFederationPlugin as default
*/
export = UniversalFederationPlugin;
//# sourceMappingURL=UniversalFederationPlugin.d.ts.map

View File

@@ -0,0 +1,66 @@
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
const require_runtime = require('../../_virtual/_rolldown/runtime.js');
const require_src_plugins_StreamingTargetPlugin = require('./StreamingTargetPlugin.js');
const require_src_plugins_NodeFederationPlugin = require('./NodeFederationPlugin.js');
let _module_federation_sdk_normalize_webpack_path = require("@module-federation/sdk/normalize-webpack-path");
let _module_federation_enhanced_webpack = require("@module-federation/enhanced/webpack");
//#region src/plugins/UniversalFederationPlugin.ts
/**
* Importing necessary plugins and types
*/
const resolveRuntimePluginPath = () => require.resolve("../runtimePlugin.js");
/**
* Class representing a UniversalFederationPlugin
*/
var UniversalFederationPlugin = class {
/**
* Create a UniversalFederationPlugin
* @param {NodeFederationOptions} options - The options for the plugin
* @param {NodeFederationContext} context - The context for the plugin
*/
constructor(options, context) {
this._options = options || {};
this.context = context || {};
this.name = "ModuleFederationPlugin";
if (this._options.useRuntimePlugin && this._options.isServer) {
const runtimePluginPath = resolveRuntimePluginPath();
this._options.runtimePlugins = this._options.runtimePlugins ? this._options.runtimePlugins.concat([runtimePluginPath]) : [runtimePluginPath];
}
}
updateCompilerOptions(compiler) {
compiler.options.output.chunkFormat = "commonjs";
if (compiler.options.output.enabledLibraryTypes === void 0) compiler.options.output.enabledLibraryTypes = ["commonjs-module"];
else compiler.options.output.enabledLibraryTypes.push("commonjs-module");
const chunkFileName = compiler.options?.output?.chunkFilename;
const uniqueName = compiler?.options?.output?.uniqueName || this._options.name;
if (typeof chunkFileName === "string" && uniqueName && !chunkFileName.includes(uniqueName)) {
const suffix = `-[contenthash].js`;
compiler.options.output.chunkFilename = chunkFileName.replace(".js", suffix);
}
}
/**
* Apply the plugin to the compiler
* @param {Compiler} compiler - The webpack compiler
*/
apply(compiler) {
const { isServer, debug, useRuntimePlugin, ...options } = this._options;
const { webpack } = compiler;
if (!process.env["FEDERATION_WEBPACK_PATH"]) process.env["FEDERATION_WEBPACK_PATH"] = (0, _module_federation_sdk_normalize_webpack_path.getWebpackPath)(compiler);
if (isServer || compiler.options.name === "server" || compiler.options.target === "node" || compiler.options.target === "async-node") if (useRuntimePlugin) {
this.updateCompilerOptions(compiler);
new _module_federation_enhanced_webpack.ModuleFederationPlugin({ ...options }).apply(compiler);
} else {
new require_src_plugins_NodeFederationPlugin.default(options, this.context).apply(compiler);
new require_src_plugins_StreamingTargetPlugin.default({
...options,
debug
}).apply(compiler);
}
else new _module_federation_enhanced_webpack.ModuleFederationPlugin(options).apply(compiler);
}
};
//#endregion
exports.default = UniversalFederationPlugin;
//# sourceMappingURL=UniversalFederationPlugin.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,65 @@
import { __require } from "../../_virtual/_rolldown/runtime.mjs";
import StreamingTargetPlugin from "./StreamingTargetPlugin.mjs";
import NodeFederationPlugin from "./NodeFederationPlugin.mjs";
import { getWebpackPath } from "@module-federation/sdk/normalize-webpack-path";
import { ModuleFederationPlugin } from "@module-federation/enhanced/webpack";
//#region src/plugins/UniversalFederationPlugin.ts
/**
* Importing necessary plugins and types
*/
const resolveRuntimePluginPath = () => __require.resolve("../runtimePlugin.mjs");
/**
* Class representing a UniversalFederationPlugin
*/
var UniversalFederationPlugin = class {
/**
* Create a UniversalFederationPlugin
* @param {NodeFederationOptions} options - The options for the plugin
* @param {NodeFederationContext} context - The context for the plugin
*/
constructor(options, context) {
this._options = options || {};
this.context = context || {};
this.name = "ModuleFederationPlugin";
if (this._options.useRuntimePlugin && this._options.isServer) {
const runtimePluginPath = resolveRuntimePluginPath();
this._options.runtimePlugins = this._options.runtimePlugins ? this._options.runtimePlugins.concat([runtimePluginPath]) : [runtimePluginPath];
}
}
updateCompilerOptions(compiler) {
compiler.options.output.chunkFormat = "commonjs";
if (compiler.options.output.enabledLibraryTypes === void 0) compiler.options.output.enabledLibraryTypes = ["commonjs-module"];
else compiler.options.output.enabledLibraryTypes.push("commonjs-module");
const chunkFileName = compiler.options?.output?.chunkFilename;
const uniqueName = compiler?.options?.output?.uniqueName || this._options.name;
if (typeof chunkFileName === "string" && uniqueName && !chunkFileName.includes(uniqueName)) {
const suffix = `-[contenthash].js`;
compiler.options.output.chunkFilename = chunkFileName.replace(".js", suffix);
}
}
/**
* Apply the plugin to the compiler
* @param {Compiler} compiler - The webpack compiler
*/
apply(compiler) {
const { isServer, debug, useRuntimePlugin, ...options } = this._options;
const { webpack } = compiler;
if (!process.env["FEDERATION_WEBPACK_PATH"]) process.env["FEDERATION_WEBPACK_PATH"] = getWebpackPath(compiler);
if (isServer || compiler.options.name === "server" || compiler.options.target === "node" || compiler.options.target === "async-node") if (useRuntimePlugin) {
this.updateCompilerOptions(compiler);
new ModuleFederationPlugin({ ...options }).apply(compiler);
} else {
new NodeFederationPlugin(options, this.context).apply(compiler);
new StreamingTargetPlugin({
...options,
debug
}).apply(compiler);
}
else new ModuleFederationPlugin(options).apply(compiler);
}
};
//#endregion
export { UniversalFederationPlugin as default };
//# sourceMappingURL=UniversalFederationPlugin.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,9 @@
import { Compiler, WebpackPluginInstance } from "webpack";
//#region src/plugins/UniverseEntryChunkTrackerPlugin.d.ts
declare class UniverseEntryChunkTrackerPlugin implements WebpackPluginInstance {
apply(compiler: Compiler): void;
}
//#endregion
export { UniverseEntryChunkTrackerPlugin as default };
//# sourceMappingURL=UniverseEntryChunkTrackerPlugin.d.mts.map

View File

@@ -0,0 +1,8 @@
import { Compiler, WebpackPluginInstance } from "webpack";
//#region src/plugins/UniverseEntryChunkTrackerPlugin.d.ts
declare class UniverseEntryChunkTrackerPlugin implements WebpackPluginInstance {
apply(compiler: Compiler): void;
}
export = UniverseEntryChunkTrackerPlugin;
//# sourceMappingURL=UniverseEntryChunkTrackerPlugin.d.ts.map

View File

@@ -0,0 +1,25 @@
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
//#region src/plugins/UniverseEntryChunkTrackerPlugin.ts
var UniverseEntryChunkTrackerPlugin = class {
apply(compiler) {
const dataUrl = `data:text/javascript;base64,${Buffer.from(`
if(typeof module !== 'undefined') {
globalThis.entryChunkCache = globalThis.entryChunkCache || new Set();
module.filename && globalThis.entryChunkCache.add(module.filename);
if(module.children) {
module.children.forEach(function(c) {
c.filename && globalThis.entryChunkCache.add(c.filename);
})
}
}
`, "utf8").toString("base64")}`;
compiler.hooks.afterPlugins.tap("UniverseEntryChunkTrackerPlugin", () => {
new compiler.webpack.EntryPlugin(compiler.context, dataUrl, {}).apply(compiler);
});
}
};
//#endregion
exports.default = UniverseEntryChunkTrackerPlugin;
//# sourceMappingURL=UniverseEntryChunkTrackerPlugin.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"UniverseEntryChunkTrackerPlugin.js","names":[],"sources":["../../../src/plugins/UniverseEntryChunkTrackerPlugin.ts"],"sourcesContent":["import type { WebpackPluginInstance, Compiler } from 'webpack';\n\nclass UniverseEntryChunkTrackerPlugin implements WebpackPluginInstance {\n apply(compiler: Compiler) {\n const code = `\n if(typeof module !== 'undefined') {\n globalThis.entryChunkCache = globalThis.entryChunkCache || new Set();\n module.filename && globalThis.entryChunkCache.add(module.filename);\n if(module.children) {\n module.children.forEach(function(c) {\n c.filename && globalThis.entryChunkCache.add(c.filename);\n })\n}\n }\n `;\n const base64Code = Buffer.from(code, 'utf8').toString('base64');\n const dataUrl = `data:text/javascript;base64,${base64Code}`;\n\n compiler.hooks.afterPlugins.tap('UniverseEntryChunkTrackerPlugin', () => {\n new compiler.webpack.EntryPlugin(compiler.context, dataUrl, {}).apply(\n compiler,\n );\n });\n }\n}\n\nexport default UniverseEntryChunkTrackerPlugin;\n"],"mappings":";;;AAEA,IAAM,kCAAN,MAAuE;CACrE,MAAM,UAAoB;EAaxB,MAAM,UAAU,+BADG,OAAO,KAXb;;;;;;;;;;OAWwB,OAAO,CAAC,SAAS,SAAS;AAG/D,WAAS,MAAM,aAAa,IAAI,yCAAyC;AACvE,OAAI,SAAS,QAAQ,YAAY,SAAS,SAAS,SAAS,EAAE,CAAC,CAAC,MAC9D,SACD;IACD"}

View File

@@ -0,0 +1,23 @@
//#region src/plugins/UniverseEntryChunkTrackerPlugin.ts
var UniverseEntryChunkTrackerPlugin = class {
apply(compiler) {
const dataUrl = `data:text/javascript;base64,${Buffer.from(`
if(typeof module !== 'undefined') {
globalThis.entryChunkCache = globalThis.entryChunkCache || new Set();
module.filename && globalThis.entryChunkCache.add(module.filename);
if(module.children) {
module.children.forEach(function(c) {
c.filename && globalThis.entryChunkCache.add(c.filename);
})
}
}
`, "utf8").toString("base64")}`;
compiler.hooks.afterPlugins.tap("UniverseEntryChunkTrackerPlugin", () => {
new compiler.webpack.EntryPlugin(compiler.context, dataUrl, {}).apply(compiler);
});
}
};
//#endregion
export { UniverseEntryChunkTrackerPlugin as default };
//# sourceMappingURL=UniverseEntryChunkTrackerPlugin.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"UniverseEntryChunkTrackerPlugin.mjs","names":[],"sources":["../../../src/plugins/UniverseEntryChunkTrackerPlugin.ts"],"sourcesContent":["import type { WebpackPluginInstance, Compiler } from 'webpack';\n\nclass UniverseEntryChunkTrackerPlugin implements WebpackPluginInstance {\n apply(compiler: Compiler) {\n const code = `\n if(typeof module !== 'undefined') {\n globalThis.entryChunkCache = globalThis.entryChunkCache || new Set();\n module.filename && globalThis.entryChunkCache.add(module.filename);\n if(module.children) {\n module.children.forEach(function(c) {\n c.filename && globalThis.entryChunkCache.add(c.filename);\n })\n}\n }\n `;\n const base64Code = Buffer.from(code, 'utf8').toString('base64');\n const dataUrl = `data:text/javascript;base64,${base64Code}`;\n\n compiler.hooks.afterPlugins.tap('UniverseEntryChunkTrackerPlugin', () => {\n new compiler.webpack.EntryPlugin(compiler.context, dataUrl, {}).apply(\n compiler,\n );\n });\n }\n}\n\nexport default UniverseEntryChunkTrackerPlugin;\n"],"mappings":";AAEA,IAAM,kCAAN,MAAuE;CACrE,MAAM,UAAoB;EAaxB,MAAM,UAAU,+BADG,OAAO,KAXb;;;;;;;;;;OAWwB,OAAO,CAAC,SAAS,SAAS;AAG/D,WAAS,MAAM,aAAa,IAAI,yCAAyC;AACvE,OAAI,SAAS,QAAQ,YAAY,SAAS,SAAS,SAAS,EAAE,CAAC,CAAC,MAC9D,SACD;IACD"}

View File

@@ -0,0 +1,55 @@
import { Chunk, ChunkGraph } from "webpack";
//#region src/plugins/webpackChunkUtilities.d.ts
/**
* Generates the hot module replacement (HMR) code.
* @param {boolean} withHmr - Flag indicating whether HMR is enabled.
* @param {string} rootOutputDir - The root output directory.
* @returns {string} - The generated HMR code.
*/
declare function generateHmrCode(withHmr: boolean, rootOutputDir: string): string;
/**
* Retrieves the initial chunk IDs.
* @param {Chunk} chunk - The chunk object.
* @param {ChunkGraph} chunkGraph - The chunk graph object.
* @param {any} chunkHasJs - Function to check if a chunk has JavaScript.
* @returns {Set} - The set of initial chunk IDs.
*/
declare function getInitialChunkIds(chunk: Chunk, chunkGraph: ChunkGraph, chunkHasJs: any): Set<Chunk.ChunkId>;
/**
* Generates the loading code for chunks.
* @param {boolean} withLoading - Flag indicating whether chunk loading is enabled.
* @param {string} fn - The function name.
* @param {any} hasJsMatcher - Function to check if a chunk has JavaScript.
* @param {string} rootOutputDir - The root output directory.
* @param {Record<string, string>} remotes - The remotes object.
* @param {string | undefined} name - The name of the chunk.
* @returns {string} - The generated loading code.
*/
declare function generateLoadingCode(withLoading: boolean, fn: string, hasJsMatcher: any, rootOutputDir: string, remotes: Record<string, string>, name: string | undefined): string;
/**
* Generates the HMR manifest code.
* @param {boolean} withHmrManifest - Flag indicating whether HMR manifest is enabled.
* @param {string} rootOutputDir - The root output directory.
* @returns {string} - The generated HMR manifest code.
*/
declare function generateHmrManifestCode(withHmrManifest: boolean, rootOutputDir: string): string;
/**
* Handles the on chunk load event.
* @param {boolean} withOnChunkLoad - Flag indicating whether on chunk load event is enabled.
* @param {any} runtimeTemplate - The runtime template.
* @returns {string} - The generated on chunk load event handler.
*/
declare function handleOnChunkLoad(withOnChunkLoad: boolean, runtimeTemplate: any): string;
/**
* Generates the load script for server-side execution. This function creates a script that loads a remote module
* and executes it in the current context. It supports both browser and Node.js environments.
* @param {any} runtimeTemplate - The runtime template used to generate the load script.
* @returns {string} - The generated load script.
*/
declare function generateLoadScript(runtimeTemplate: any): string;
declare function generateInstallChunk(runtimeTemplate: any, withOnChunkLoad: boolean): string;
declare function generateExternalInstallChunkCode(withExternalInstallChunk: boolean, debug: boolean | undefined): string;
//#endregion
export { generateExternalInstallChunkCode, generateHmrCode, generateHmrManifestCode, generateInstallChunk, generateLoadScript, generateLoadingCode, getInitialChunkIds, handleOnChunkLoad };
//# sourceMappingURL=webpackChunkUtilities.d.mts.map

View File

@@ -0,0 +1,55 @@
import { Chunk, ChunkGraph } from "webpack";
//#region src/plugins/webpackChunkUtilities.d.ts
/**
* Generates the hot module replacement (HMR) code.
* @param {boolean} withHmr - Flag indicating whether HMR is enabled.
* @param {string} rootOutputDir - The root output directory.
* @returns {string} - The generated HMR code.
*/
declare function generateHmrCode(withHmr: boolean, rootOutputDir: string): string;
/**
* Retrieves the initial chunk IDs.
* @param {Chunk} chunk - The chunk object.
* @param {ChunkGraph} chunkGraph - The chunk graph object.
* @param {any} chunkHasJs - Function to check if a chunk has JavaScript.
* @returns {Set} - The set of initial chunk IDs.
*/
declare function getInitialChunkIds(chunk: Chunk, chunkGraph: ChunkGraph, chunkHasJs: any): Set<Chunk.ChunkId>;
/**
* Generates the loading code for chunks.
* @param {boolean} withLoading - Flag indicating whether chunk loading is enabled.
* @param {string} fn - The function name.
* @param {any} hasJsMatcher - Function to check if a chunk has JavaScript.
* @param {string} rootOutputDir - The root output directory.
* @param {Record<string, string>} remotes - The remotes object.
* @param {string | undefined} name - The name of the chunk.
* @returns {string} - The generated loading code.
*/
declare function generateLoadingCode(withLoading: boolean, fn: string, hasJsMatcher: any, rootOutputDir: string, remotes: Record<string, string>, name: string | undefined): string;
/**
* Generates the HMR manifest code.
* @param {boolean} withHmrManifest - Flag indicating whether HMR manifest is enabled.
* @param {string} rootOutputDir - The root output directory.
* @returns {string} - The generated HMR manifest code.
*/
declare function generateHmrManifestCode(withHmrManifest: boolean, rootOutputDir: string): string;
/**
* Handles the on chunk load event.
* @param {boolean} withOnChunkLoad - Flag indicating whether on chunk load event is enabled.
* @param {any} runtimeTemplate - The runtime template.
* @returns {string} - The generated on chunk load event handler.
*/
declare function handleOnChunkLoad(withOnChunkLoad: boolean, runtimeTemplate: any): string;
/**
* Generates the load script for server-side execution. This function creates a script that loads a remote module
* and executes it in the current context. It supports both browser and Node.js environments.
* @param {any} runtimeTemplate - The runtime template used to generate the load script.
* @returns {string} - The generated load script.
*/
declare function generateLoadScript(runtimeTemplate: any): string;
declare function generateInstallChunk(runtimeTemplate: any, withOnChunkLoad: boolean): string;
declare function generateExternalInstallChunkCode(withExternalInstallChunk: boolean, debug: boolean | undefined): string;
//#endregion
export { generateExternalInstallChunkCode, generateHmrCode, generateHmrManifestCode, generateInstallChunk, generateLoadScript, generateLoadingCode, getInitialChunkIds, handleOnChunkLoad };
//# sourceMappingURL=webpackChunkUtilities.d.ts.map

View File

@@ -0,0 +1,242 @@
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const require_runtime = require('../../_virtual/_rolldown/runtime.js');
let _module_federation_sdk_normalize_webpack_path = require("@module-federation/sdk/normalize-webpack-path");
//#region src/plugins/webpackChunkUtilities.ts
const { RuntimeGlobals, Template } = require((0, _module_federation_sdk_normalize_webpack_path.normalizeWebpackPath)("webpack"));
/**
* Generates the hot module replacement (HMR) code.
* @param {boolean} withHmr - Flag indicating whether HMR is enabled.
* @param {string} rootOutputDir - The root output directory.
* @returns {string} - The generated HMR code.
*/
function generateHmrCode(withHmr, rootOutputDir) {
if (!withHmr) return "// no HMR";
return Template.asString([
"function loadUpdateChunk(chunkId, updatedModulesList) {",
Template.indent([
"return new Promise(function(resolve, reject) {",
Template.indent([
`var filename = require('path').join(__dirname, ${JSON.stringify(rootOutputDir)} + ${RuntimeGlobals.getChunkUpdateScriptFilename}(chunkId));`,
"require('fs').readFile(filename, 'utf-8', function(err, content) {",
Template.indent([
"if(err) return reject(err);",
"var update = {};",
"require('vm').runInThisContext('(function(exports, require, __dirname, __filename) {' + content + '\\n})', filename)(update, require, require('path').dirname(filename), filename);",
"var updatedModules = update.modules;",
"var runtime = update.runtime;",
"for(var moduleId in updatedModules) {",
Template.indent([
`if(${RuntimeGlobals.hasOwnProperty}(updatedModules, moduleId)) {`,
Template.indent([`currentUpdate[moduleId] = updatedModules[moduleId];`, "if(updatedModulesList) updatedModulesList.push(moduleId);"]),
"}"
]),
"}",
"if(runtime) currentUpdateRuntime.push(runtime);",
"resolve();"
]),
"});"
]),
"});"
]),
"}",
"",
Template.getFunctionContent(require("webpack/lib/hmr/JavascriptHotModuleReplacement.runtime.js")).replace(/\$key\$/g, "readFileVm").replace(/\$installedChunks\$/g, "installedChunks").replace(/\$loadUpdateChunk\$/g, "loadUpdateChunk").replace(/\$moduleCache\$/g, RuntimeGlobals.moduleCache).replace(/\$moduleFactories\$/g, RuntimeGlobals.moduleFactories).replace(/\$ensureChunkHandlers\$/g, RuntimeGlobals.ensureChunkHandlers).replace(/\$hasOwnProperty\$/g, RuntimeGlobals.hasOwnProperty).replace(/\$hmrModuleData\$/g, RuntimeGlobals.hmrModuleData).replace(/\$hmrDownloadUpdateHandlers\$/g, RuntimeGlobals.hmrDownloadUpdateHandlers).replace(/\$hmrInvalidateModuleHandlers\$/g, RuntimeGlobals.hmrInvalidateModuleHandlers)
]);
}
/**
* Retrieves the initial chunk IDs.
* @param {Chunk} chunk - The chunk object.
* @param {ChunkGraph} chunkGraph - The chunk graph object.
* @param {any} chunkHasJs - Function to check if a chunk has JavaScript.
* @returns {Set} - The set of initial chunk IDs.
*/
function getInitialChunkIds(chunk, chunkGraph, chunkHasJs) {
const initialChunkIds = new Set(chunk.ids);
for (const c of chunk.getAllInitialChunks()) {
if (c === chunk || chunkHasJs(c, chunkGraph)) continue;
if (c.ids) for (const id of c.ids) initialChunkIds.add(id);
for (const c of chunk.getAllAsyncChunks()) {
if (c === chunk || chunkHasJs(c, chunkGraph)) continue;
if (c.ids) for (const id of c.ids) initialChunkIds.add(id);
}
}
return initialChunkIds;
}
/**
* Generates the loading code for chunks.
* @param {boolean} withLoading - Flag indicating whether chunk loading is enabled.
* @param {string} fn - The function name.
* @param {any} hasJsMatcher - Function to check if a chunk has JavaScript.
* @param {string} rootOutputDir - The root output directory.
* @param {Record<string, string>} remotes - The remotes object.
* @param {string | undefined} name - The name of the chunk.
* @returns {string} - The generated loading code.
*/
function generateLoadingCode(withLoading, fn, hasJsMatcher, rootOutputDir, remotes, name) {
if (!withLoading) return "// no chunk loading";
return Template.asString([
"// Dynamic filesystem chunk loading for javascript",
`${fn}.readFileVm = function(chunkId, promises) {`,
hasJsMatcher !== false ? Template.indent([
"var installedChunkData = installedChunks[chunkId];",
"if(installedChunkData !== 0) { // 0 means \"already installed\".",
Template.indent([
"// array of [resolve, reject, promise] means \"currently loading\"",
"if(installedChunkData) {",
Template.indent(["promises.push(installedChunkData[2]);"]),
"} else {",
Template.indent([
hasJsMatcher === true ? "if(true) { // all chunks have JS" : `if(${hasJsMatcher("chunkId")}) {`,
Template.indent([
"// load the chunk and return promise to it",
"var promise = new Promise(async function(resolve, reject) {",
Template.indent([
"installedChunkData = installedChunks[chunkId] = [resolve, reject];",
"function installChunkCallback(error,chunk){",
Template.indent(["if(error) return reject(error);", "installChunk(chunk);"]),
"}",
"var fs = typeof process !== \"undefined\" ? require('fs') : false;",
`var filename = typeof process !== "undefined" ? require('path').join(__dirname, ${JSON.stringify(rootOutputDir)} + ${RuntimeGlobals.getChunkScriptFilename}(chunkId)) : false;`,
"if(fs && fs.existsSync(filename)) {",
Template.indent([`loadChunkStrategy('filesystem', chunkId, ${JSON.stringify(rootOutputDir)}, remotes, installChunkCallback);`]),
"} else { ",
Template.indent([
`var remotes = ${JSON.stringify(Object.values(remotes).reduce((acc, remote) => {
const [global, url] = remote.split("@");
acc[global] = url;
return acc;
}, {}))};`,
`var chunkName = ${RuntimeGlobals.getChunkScriptFilename}(chunkId);`,
"const loadingStrategy = typeof process !== 'undefined' ? 'http-vm' : 'http-eval';",
`loadChunkStrategy(loadingStrategy, chunkName,${RuntimeGlobals.require}.federation.initOptions.name, ${RuntimeGlobals.require}.federation.initOptions.remotes, installChunkCallback);`
]),
"}"
]),
"});",
"promises.push(installedChunkData[2] = promise);"
]),
"} else installedChunks[chunkId] = 0;"
]),
"}"
]),
"}"
]) : Template.indent(["installedChunks[chunkId] = 0;"]),
"};"
]);
}
/**
* Generates the HMR manifest code.
* @param {boolean} withHmrManifest - Flag indicating whether HMR manifest is enabled.
* @param {string} rootOutputDir - The root output directory.
* @returns {string} - The generated HMR manifest code.
*/
function generateHmrManifestCode(withHmrManifest, rootOutputDir) {
if (!withHmrManifest) return "// no HMR manifest";
return Template.asString([
`${RuntimeGlobals.hmrDownloadManifest} = function() {`,
Template.indent([
"return new Promise(function(resolve, reject) {",
Template.indent([
`var filename = require('path').join(__dirname, ${JSON.stringify(rootOutputDir)} + ${RuntimeGlobals.getUpdateManifestFilename}());`,
"require('fs').readFile(filename, 'utf-8', function(err, content) {",
Template.indent([
"if(err) {",
Template.indent(["if(err.code === \"ENOENT\") return resolve();", "return reject(err);"]),
"}",
"try { resolve(JSON.parse(content)); }",
"catch(e) { reject(e); }"
]),
"});"
]),
"});"
]),
"}"
]);
}
/**
* Handles the on chunk load event.
* @param {boolean} withOnChunkLoad - Flag indicating whether on chunk load event is enabled.
* @param {any} runtimeTemplate - The runtime template.
* @returns {string} - The generated on chunk load event handler.
*/
function handleOnChunkLoad(withOnChunkLoad, runtimeTemplate) {
if (withOnChunkLoad) return `${RuntimeGlobals.onChunksLoaded}.readFileVm = ${runtimeTemplate.returningFunction("installedChunks[chunkId] === 0", "chunkId")};`;
else return "// no on chunks loaded";
}
/**
* Generates the load script for server-side execution. This function creates a script that loads a remote module
* and executes it in the current context. It supports both browser and Node.js environments.
* @param {any} runtimeTemplate - The runtime template used to generate the load script.
* @returns {string} - The generated load script.
*/
function generateLoadScript(runtimeTemplate) {
return Template.asString(["// load script equivalent for server side", `${RuntimeGlobals.loadScript} = ${runtimeTemplate.basicFunction("url, callback, chunkId", [Template.indent([`async function executeLoad(url, callback, name) {
if (!name) {
throw new Error('__webpack_require__.l name is required for ' + url);
}
const usesInternalRef = name.startsWith('__webpack_require__')
if (usesInternalRef) {
const regex = /__webpack_require__\\.federation\\.instance\\.moduleCache\\.get\\(([^)]+)\\)/;
const match = name.match(regex);
if (match) {
name = match[1].replace(/["']/g, '');
}
}
try {
const federation = ${RuntimeGlobals.require}.federation;
const res = await ${RuntimeGlobals.require}.federation.runtime.loadScriptNode(url, { attrs: {} });
const enhancedRemote = federation.instance.initRawContainer(name, url, res);
// use normal global assignment
if(!usesInternalRef && !globalThis[name]) {
globalThis[name] = enhancedRemote
}
callback(enhancedRemote);
} catch (error) {
callback(error);
}
}`, `executeLoad(url, callback, chunkId);`])])}`]);
}
function generateInstallChunk(runtimeTemplate, withOnChunkLoad) {
return `var installChunk = ${runtimeTemplate.basicFunction("chunk", [
"var moreModules = chunk.modules, chunkIds = chunk.ids, runtime = chunk.runtime;",
"for(var moduleId in moreModules) {",
Template.indent([
`if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`,
Template.indent([`${RuntimeGlobals.moduleFactories}[moduleId] = moreModules[moduleId];`]),
"}"
]),
"}",
"if(runtime) runtime(__webpack_require__);",
"for(var i = 0; i < chunkIds.length; i++) {",
Template.indent([
"if(installedChunks[chunkIds[i]]) {",
Template.indent(["installedChunks[chunkIds[i]][0]();"]),
"}",
"installedChunks[chunkIds[i]] = 0;"
]),
"}",
withOnChunkLoad ? `${RuntimeGlobals.onChunksLoaded}();` : ""
])};`;
}
function generateExternalInstallChunkCode(withExternalInstallChunk, debug) {
if (!withExternalInstallChunk) return "// no external install chunk";
return Template.asString([
"module.exports = __webpack_require__;",
`${RuntimeGlobals.externalInstallChunk} = function(){`,
debug ? `console.debug('node: webpack installing to install chunk id:', arguments['0'].id);` : "",
`return installChunk.apply(this, arguments)};`
]);
}
//#endregion
exports.generateExternalInstallChunkCode = generateExternalInstallChunkCode;
exports.generateHmrCode = generateHmrCode;
exports.generateHmrManifestCode = generateHmrManifestCode;
exports.generateInstallChunk = generateInstallChunk;
exports.generateLoadScript = generateLoadScript;
exports.generateLoadingCode = generateLoadingCode;
exports.getInitialChunkIds = getInitialChunkIds;
exports.handleOnChunkLoad = handleOnChunkLoad;
//# sourceMappingURL=webpackChunkUtilities.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,234 @@
import { __require } from "../../_virtual/_rolldown/runtime.mjs";
import { normalizeWebpackPath } from "@module-federation/sdk/normalize-webpack-path";
//#region src/plugins/webpackChunkUtilities.ts
const { RuntimeGlobals, Template } = __require(normalizeWebpackPath("webpack"));
/**
* Generates the hot module replacement (HMR) code.
* @param {boolean} withHmr - Flag indicating whether HMR is enabled.
* @param {string} rootOutputDir - The root output directory.
* @returns {string} - The generated HMR code.
*/
function generateHmrCode(withHmr, rootOutputDir) {
if (!withHmr) return "// no HMR";
return Template.asString([
"function loadUpdateChunk(chunkId, updatedModulesList) {",
Template.indent([
"return new Promise(function(resolve, reject) {",
Template.indent([
`var filename = require('path').join(__dirname, ${JSON.stringify(rootOutputDir)} + ${RuntimeGlobals.getChunkUpdateScriptFilename}(chunkId));`,
"require('fs').readFile(filename, 'utf-8', function(err, content) {",
Template.indent([
"if(err) return reject(err);",
"var update = {};",
"require('vm').runInThisContext('(function(exports, require, __dirname, __filename) {' + content + '\\n})', filename)(update, require, require('path').dirname(filename), filename);",
"var updatedModules = update.modules;",
"var runtime = update.runtime;",
"for(var moduleId in updatedModules) {",
Template.indent([
`if(${RuntimeGlobals.hasOwnProperty}(updatedModules, moduleId)) {`,
Template.indent([`currentUpdate[moduleId] = updatedModules[moduleId];`, "if(updatedModulesList) updatedModulesList.push(moduleId);"]),
"}"
]),
"}",
"if(runtime) currentUpdateRuntime.push(runtime);",
"resolve();"
]),
"});"
]),
"});"
]),
"}",
"",
Template.getFunctionContent(__require("webpack/lib/hmr/JavascriptHotModuleReplacement.runtime.js")).replace(/\$key\$/g, "readFileVm").replace(/\$installedChunks\$/g, "installedChunks").replace(/\$loadUpdateChunk\$/g, "loadUpdateChunk").replace(/\$moduleCache\$/g, RuntimeGlobals.moduleCache).replace(/\$moduleFactories\$/g, RuntimeGlobals.moduleFactories).replace(/\$ensureChunkHandlers\$/g, RuntimeGlobals.ensureChunkHandlers).replace(/\$hasOwnProperty\$/g, RuntimeGlobals.hasOwnProperty).replace(/\$hmrModuleData\$/g, RuntimeGlobals.hmrModuleData).replace(/\$hmrDownloadUpdateHandlers\$/g, RuntimeGlobals.hmrDownloadUpdateHandlers).replace(/\$hmrInvalidateModuleHandlers\$/g, RuntimeGlobals.hmrInvalidateModuleHandlers)
]);
}
/**
* Retrieves the initial chunk IDs.
* @param {Chunk} chunk - The chunk object.
* @param {ChunkGraph} chunkGraph - The chunk graph object.
* @param {any} chunkHasJs - Function to check if a chunk has JavaScript.
* @returns {Set} - The set of initial chunk IDs.
*/
function getInitialChunkIds(chunk, chunkGraph, chunkHasJs) {
const initialChunkIds = new Set(chunk.ids);
for (const c of chunk.getAllInitialChunks()) {
if (c === chunk || chunkHasJs(c, chunkGraph)) continue;
if (c.ids) for (const id of c.ids) initialChunkIds.add(id);
for (const c of chunk.getAllAsyncChunks()) {
if (c === chunk || chunkHasJs(c, chunkGraph)) continue;
if (c.ids) for (const id of c.ids) initialChunkIds.add(id);
}
}
return initialChunkIds;
}
/**
* Generates the loading code for chunks.
* @param {boolean} withLoading - Flag indicating whether chunk loading is enabled.
* @param {string} fn - The function name.
* @param {any} hasJsMatcher - Function to check if a chunk has JavaScript.
* @param {string} rootOutputDir - The root output directory.
* @param {Record<string, string>} remotes - The remotes object.
* @param {string | undefined} name - The name of the chunk.
* @returns {string} - The generated loading code.
*/
function generateLoadingCode(withLoading, fn, hasJsMatcher, rootOutputDir, remotes, name) {
if (!withLoading) return "// no chunk loading";
return Template.asString([
"// Dynamic filesystem chunk loading for javascript",
`${fn}.readFileVm = function(chunkId, promises) {`,
hasJsMatcher !== false ? Template.indent([
"var installedChunkData = installedChunks[chunkId];",
"if(installedChunkData !== 0) { // 0 means \"already installed\".",
Template.indent([
"// array of [resolve, reject, promise] means \"currently loading\"",
"if(installedChunkData) {",
Template.indent(["promises.push(installedChunkData[2]);"]),
"} else {",
Template.indent([
hasJsMatcher === true ? "if(true) { // all chunks have JS" : `if(${hasJsMatcher("chunkId")}) {`,
Template.indent([
"// load the chunk and return promise to it",
"var promise = new Promise(async function(resolve, reject) {",
Template.indent([
"installedChunkData = installedChunks[chunkId] = [resolve, reject];",
"function installChunkCallback(error,chunk){",
Template.indent(["if(error) return reject(error);", "installChunk(chunk);"]),
"}",
"var fs = typeof process !== \"undefined\" ? require('fs') : false;",
`var filename = typeof process !== "undefined" ? require('path').join(__dirname, ${JSON.stringify(rootOutputDir)} + ${RuntimeGlobals.getChunkScriptFilename}(chunkId)) : false;`,
"if(fs && fs.existsSync(filename)) {",
Template.indent([`loadChunkStrategy('filesystem', chunkId, ${JSON.stringify(rootOutputDir)}, remotes, installChunkCallback);`]),
"} else { ",
Template.indent([
`var remotes = ${JSON.stringify(Object.values(remotes).reduce((acc, remote) => {
const [global, url] = remote.split("@");
acc[global] = url;
return acc;
}, {}))};`,
`var chunkName = ${RuntimeGlobals.getChunkScriptFilename}(chunkId);`,
"const loadingStrategy = typeof process !== 'undefined' ? 'http-vm' : 'http-eval';",
`loadChunkStrategy(loadingStrategy, chunkName,${RuntimeGlobals.require}.federation.initOptions.name, ${RuntimeGlobals.require}.federation.initOptions.remotes, installChunkCallback);`
]),
"}"
]),
"});",
"promises.push(installedChunkData[2] = promise);"
]),
"} else installedChunks[chunkId] = 0;"
]),
"}"
]),
"}"
]) : Template.indent(["installedChunks[chunkId] = 0;"]),
"};"
]);
}
/**
* Generates the HMR manifest code.
* @param {boolean} withHmrManifest - Flag indicating whether HMR manifest is enabled.
* @param {string} rootOutputDir - The root output directory.
* @returns {string} - The generated HMR manifest code.
*/
function generateHmrManifestCode(withHmrManifest, rootOutputDir) {
if (!withHmrManifest) return "// no HMR manifest";
return Template.asString([
`${RuntimeGlobals.hmrDownloadManifest} = function() {`,
Template.indent([
"return new Promise(function(resolve, reject) {",
Template.indent([
`var filename = require('path').join(__dirname, ${JSON.stringify(rootOutputDir)} + ${RuntimeGlobals.getUpdateManifestFilename}());`,
"require('fs').readFile(filename, 'utf-8', function(err, content) {",
Template.indent([
"if(err) {",
Template.indent(["if(err.code === \"ENOENT\") return resolve();", "return reject(err);"]),
"}",
"try { resolve(JSON.parse(content)); }",
"catch(e) { reject(e); }"
]),
"});"
]),
"});"
]),
"}"
]);
}
/**
* Handles the on chunk load event.
* @param {boolean} withOnChunkLoad - Flag indicating whether on chunk load event is enabled.
* @param {any} runtimeTemplate - The runtime template.
* @returns {string} - The generated on chunk load event handler.
*/
function handleOnChunkLoad(withOnChunkLoad, runtimeTemplate) {
if (withOnChunkLoad) return `${RuntimeGlobals.onChunksLoaded}.readFileVm = ${runtimeTemplate.returningFunction("installedChunks[chunkId] === 0", "chunkId")};`;
else return "// no on chunks loaded";
}
/**
* Generates the load script for server-side execution. This function creates a script that loads a remote module
* and executes it in the current context. It supports both browser and Node.js environments.
* @param {any} runtimeTemplate - The runtime template used to generate the load script.
* @returns {string} - The generated load script.
*/
function generateLoadScript(runtimeTemplate) {
return Template.asString(["// load script equivalent for server side", `${RuntimeGlobals.loadScript} = ${runtimeTemplate.basicFunction("url, callback, chunkId", [Template.indent([`async function executeLoad(url, callback, name) {
if (!name) {
throw new Error('__webpack_require__.l name is required for ' + url);
}
const usesInternalRef = name.startsWith('__webpack_require__')
if (usesInternalRef) {
const regex = /__webpack_require__\\.federation\\.instance\\.moduleCache\\.get\\(([^)]+)\\)/;
const match = name.match(regex);
if (match) {
name = match[1].replace(/["']/g, '');
}
}
try {
const federation = ${RuntimeGlobals.require}.federation;
const res = await ${RuntimeGlobals.require}.federation.runtime.loadScriptNode(url, { attrs: {} });
const enhancedRemote = federation.instance.initRawContainer(name, url, res);
// use normal global assignment
if(!usesInternalRef && !globalThis[name]) {
globalThis[name] = enhancedRemote
}
callback(enhancedRemote);
} catch (error) {
callback(error);
}
}`, `executeLoad(url, callback, chunkId);`])])}`]);
}
function generateInstallChunk(runtimeTemplate, withOnChunkLoad) {
return `var installChunk = ${runtimeTemplate.basicFunction("chunk", [
"var moreModules = chunk.modules, chunkIds = chunk.ids, runtime = chunk.runtime;",
"for(var moduleId in moreModules) {",
Template.indent([
`if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`,
Template.indent([`${RuntimeGlobals.moduleFactories}[moduleId] = moreModules[moduleId];`]),
"}"
]),
"}",
"if(runtime) runtime(__webpack_require__);",
"for(var i = 0; i < chunkIds.length; i++) {",
Template.indent([
"if(installedChunks[chunkIds[i]]) {",
Template.indent(["installedChunks[chunkIds[i]][0]();"]),
"}",
"installedChunks[chunkIds[i]] = 0;"
]),
"}",
withOnChunkLoad ? `${RuntimeGlobals.onChunksLoaded}();` : ""
])};`;
}
function generateExternalInstallChunkCode(withExternalInstallChunk, debug) {
if (!withExternalInstallChunk) return "// no external install chunk";
return Template.asString([
"module.exports = __webpack_require__;",
`${RuntimeGlobals.externalInstallChunk} = function(){`,
debug ? `console.debug('node: webpack installing to install chunk id:', arguments['0'].id);` : "",
`return installChunk.apply(this, arguments)};`
]);
}
//#endregion
export { generateExternalInstallChunkCode, generateHmrCode, generateHmrManifestCode, generateInstallChunk, generateLoadScript, generateLoadingCode, getInitialChunkIds, handleOnChunkLoad };
//# sourceMappingURL=webpackChunkUtilities.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
import { ModuleFederationRuntimePlugin } from "@module-federation/runtime";
//#region src/recordDynamicRemoteEntryHashPlugin.d.ts
declare const recordDynamicRemoteEntryHashPlugin: () => ModuleFederationRuntimePlugin;
//#endregion
export { recordDynamicRemoteEntryHashPlugin as default };
//# sourceMappingURL=recordDynamicRemoteEntryHashPlugin.d.mts.map

View File

@@ -0,0 +1,6 @@
import { ModuleFederationRuntimePlugin } from "@module-federation/runtime";
//#region src/recordDynamicRemoteEntryHashPlugin.d.ts
declare const recordDynamicRemoteEntryHashPlugin: () => ModuleFederationRuntimePlugin;
export = recordDynamicRemoteEntryHashPlugin;
//# sourceMappingURL=recordDynamicRemoteEntryHashPlugin.d.ts.map

View File

@@ -0,0 +1,28 @@
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
//#region src/recordDynamicRemoteEntryHashPlugin.ts
const recordDynamicRemoteEntryHashPlugin = () => ({
name: "record-dynamic-remote-entry-hash-plugin",
beforeInit(args) {
if (!globalThis.mfHashMap) globalThis.mfHashMap = {};
return args;
},
async onLoad(args) {
const { moduleInstance } = args;
if (!moduleInstance.remoteInfo) return args;
const hashmap = globalThis.mfHashMap;
if (!hashmap) return args;
const { name, entry } = moduleInstance.remoteInfo;
if (!hashmap[name]) {
const hotReloadUtils = await Promise.resolve().then(() => require("./utils/hot-reload.js"));
await hotReloadUtils.createFetcher(entry, hotReloadUtils.getFetchModule(), name, (hash) => {
hashmap[name] = hash;
});
}
return args;
}
});
//#endregion
exports.default = recordDynamicRemoteEntryHashPlugin;
//# sourceMappingURL=recordDynamicRemoteEntryHashPlugin.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"recordDynamicRemoteEntryHashPlugin.js","names":[],"sources":["../../src/recordDynamicRemoteEntryHashPlugin.ts"],"sourcesContent":["import type { ModuleFederationRuntimePlugin } from '@module-federation/runtime';\n\nconst recordDynamicRemoteEntryHashPlugin: () => ModuleFederationRuntimePlugin =\n () => ({\n name: 'record-dynamic-remote-entry-hash-plugin',\n beforeInit(args) {\n if (!globalThis.mfHashMap) {\n globalThis.mfHashMap = {};\n }\n\n return args;\n },\n async onLoad(args) {\n const { moduleInstance } = args;\n\n if (!moduleInstance.remoteInfo) {\n return args;\n }\n const hashmap = globalThis.mfHashMap;\n\n if (!hashmap) {\n return args;\n }\n\n const { name, entry } = moduleInstance.remoteInfo;\n\n if (!hashmap[name]) {\n const hotReloadUtils = await import('./utils/hot-reload');\n const fetcher = hotReloadUtils.createFetcher(\n entry,\n hotReloadUtils.getFetchModule(),\n name,\n (hash) => {\n hashmap[name] = hash;\n },\n );\n await fetcher;\n }\n\n return args;\n },\n });\nexport default recordDynamicRemoteEntryHashPlugin;\n"],"mappings":";;;AAEA,MAAM,4CACG;CACL,MAAM;CACN,WAAW,MAAM;AACf,MAAI,CAAC,WAAW,UACd,YAAW,YAAY,EAAE;AAG3B,SAAO;;CAET,MAAM,OAAO,MAAM;EACjB,MAAM,EAAE,mBAAmB;AAE3B,MAAI,CAAC,eAAe,WAClB,QAAO;EAET,MAAM,UAAU,WAAW;AAE3B,MAAI,CAAC,QACH,QAAO;EAGT,MAAM,EAAE,MAAM,UAAU,eAAe;AAEvC,MAAI,CAAC,QAAQ,OAAO;GAClB,MAAM,iBAAiB,2CAAM;AAS7B,SARgB,eAAe,cAC7B,OACA,eAAe,gBAAgB,EAC/B,OACC,SAAS;AACR,YAAQ,QAAQ;KAEnB;;AAIH,SAAO;;CAEV"}

View File

@@ -0,0 +1,26 @@
//#region src/recordDynamicRemoteEntryHashPlugin.ts
const recordDynamicRemoteEntryHashPlugin = () => ({
name: "record-dynamic-remote-entry-hash-plugin",
beforeInit(args) {
if (!globalThis.mfHashMap) globalThis.mfHashMap = {};
return args;
},
async onLoad(args) {
const { moduleInstance } = args;
if (!moduleInstance.remoteInfo) return args;
const hashmap = globalThis.mfHashMap;
if (!hashmap) return args;
const { name, entry } = moduleInstance.remoteInfo;
if (!hashmap[name]) {
const hotReloadUtils = await import("./utils/hot-reload.mjs");
await hotReloadUtils.createFetcher(entry, hotReloadUtils.getFetchModule(), name, (hash) => {
hashmap[name] = hash;
});
}
return args;
}
});
//#endregion
export { recordDynamicRemoteEntryHashPlugin as default };
//# sourceMappingURL=recordDynamicRemoteEntryHashPlugin.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"recordDynamicRemoteEntryHashPlugin.mjs","names":[],"sources":["../../src/recordDynamicRemoteEntryHashPlugin.ts"],"sourcesContent":["import type { ModuleFederationRuntimePlugin } from '@module-federation/runtime';\n\nconst recordDynamicRemoteEntryHashPlugin: () => ModuleFederationRuntimePlugin =\n () => ({\n name: 'record-dynamic-remote-entry-hash-plugin',\n beforeInit(args) {\n if (!globalThis.mfHashMap) {\n globalThis.mfHashMap = {};\n }\n\n return args;\n },\n async onLoad(args) {\n const { moduleInstance } = args;\n\n if (!moduleInstance.remoteInfo) {\n return args;\n }\n const hashmap = globalThis.mfHashMap;\n\n if (!hashmap) {\n return args;\n }\n\n const { name, entry } = moduleInstance.remoteInfo;\n\n if (!hashmap[name]) {\n const hotReloadUtils = await import('./utils/hot-reload');\n const fetcher = hotReloadUtils.createFetcher(\n entry,\n hotReloadUtils.getFetchModule(),\n name,\n (hash) => {\n hashmap[name] = hash;\n },\n );\n await fetcher;\n }\n\n return args;\n },\n });\nexport default recordDynamicRemoteEntryHashPlugin;\n"],"mappings":";AAEA,MAAM,4CACG;CACL,MAAM;CACN,WAAW,MAAM;AACf,MAAI,CAAC,WAAW,UACd,YAAW,YAAY,EAAE;AAG3B,SAAO;;CAET,MAAM,OAAO,MAAM;EACjB,MAAM,EAAE,mBAAmB;AAE3B,MAAI,CAAC,eAAe,WAClB,QAAO;EAET,MAAM,UAAU,WAAW;AAE3B,MAAI,CAAC,QACH,QAAO;EAGT,MAAM,EAAE,MAAM,UAAU,eAAe;AAEvC,MAAI,CAAC,QAAQ,OAAO;GAClB,MAAM,iBAAiB,MAAM,OAAO;AASpC,SARgB,eAAe,cAC7B,OACA,eAAe,gBAAgB,EAC/B,OACC,SAAS;AACR,YAAQ,QAAQ;KAEnB;;AAIH,SAAO;;CAEV"}

View File

@@ -0,0 +1,27 @@
import { ModuleFederationRuntimePlugin } from "@module-federation/runtime";
//#region src/runtimePlugin.d.ts
declare const nodeRuntimeImportCache: Map<string, Promise<any>>;
declare function importNodeModule<T>(name: string): Promise<T>;
declare const resolveFile: (rootOutputDir: string, chunkId: string) => string;
declare const returnFromCache: (remoteName: string) => string | null;
declare const returnFromGlobalInstances: (remoteName: string) => string | null;
declare const loadFromFs: (filename: string, callback: (err: Error | null, chunk: any) => void) => void;
declare const fetchAndRun: (url: URL, chunkName: string, callback: (err: Error | null, chunk: any) => void, args: any) => void;
declare const resolveUrl: (remoteName: string, chunkName: string) => URL | null;
declare const loadChunk: (strategy: string, chunkId: string, rootOutputDir: string, callback: (err: Error | null, chunk: any) => void, args: any) => void;
declare const installChunk: (chunk: any, installedChunks: {
[key: string]: any;
}) => void;
declare const deleteChunk: (chunkId: string, installedChunks: {
[key: string]: any;
}) => boolean;
declare const setupScriptLoader: () => void;
declare const setupChunkHandler: (installedChunks: {
[key: string]: any;
}, args: any) => ((chunkId: string, promises: any[]) => void);
declare const setupWebpackRequirePatching: (handle: (chunkId: string, promises: any[]) => void) => void;
declare function export_default(): ModuleFederationRuntimePlugin;
//#endregion
export { export_default as default, deleteChunk, fetchAndRun, importNodeModule, installChunk, loadChunk, loadFromFs, nodeRuntimeImportCache, resolveFile, resolveUrl, returnFromCache, returnFromGlobalInstances, setupChunkHandler, setupScriptLoader, setupWebpackRequirePatching };
//# sourceMappingURL=runtimePlugin.d.mts.map

View File

@@ -0,0 +1,27 @@
import { ModuleFederationRuntimePlugin } from "@module-federation/runtime";
//#region src/runtimePlugin.d.ts
declare const nodeRuntimeImportCache: Map<string, Promise<any>>;
declare function importNodeModule<T>(name: string): Promise<T>;
declare const resolveFile: (rootOutputDir: string, chunkId: string) => string;
declare const returnFromCache: (remoteName: string) => string | null;
declare const returnFromGlobalInstances: (remoteName: string) => string | null;
declare const loadFromFs: (filename: string, callback: (err: Error | null, chunk: any) => void) => void;
declare const fetchAndRun: (url: URL, chunkName: string, callback: (err: Error | null, chunk: any) => void, args: any) => void;
declare const resolveUrl: (remoteName: string, chunkName: string) => URL | null;
declare const loadChunk: (strategy: string, chunkId: string, rootOutputDir: string, callback: (err: Error | null, chunk: any) => void, args: any) => void;
declare const installChunk: (chunk: any, installedChunks: {
[key: string]: any;
}) => void;
declare const deleteChunk: (chunkId: string, installedChunks: {
[key: string]: any;
}) => boolean;
declare const setupScriptLoader: () => void;
declare const setupChunkHandler: (installedChunks: {
[key: string]: any;
}, args: any) => ((chunkId: string, promises: any[]) => void);
declare const setupWebpackRequirePatching: (handle: (chunkId: string, promises: any[]) => void) => void;
declare function export_default(): ModuleFederationRuntimePlugin;
//#endregion
export { export_default as default, deleteChunk, fetchAndRun, importNodeModule, installChunk, loadChunk, loadFromFs, nodeRuntimeImportCache, resolveFile, resolveUrl, returnFromCache, returnFromGlobalInstances, setupChunkHandler, setupScriptLoader, setupWebpackRequirePatching };
//# sourceMappingURL=runtimePlugin.d.ts.map

View File

@@ -0,0 +1,242 @@
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
//#region src/runtimePlugin.ts
const nodeRuntimeImportCache = /* @__PURE__ */ new Map();
const CHUNK_PREVIEW_LENGTH = 240;
const getChunkPreview = (content) => content.slice(0, CHUNK_PREVIEW_LENGTH).replace(/\s+/g, " ").trim();
const enrichChunkExecutionError = (error, options) => {
const normalizedError = error instanceof Error ? error : new Error(String(error));
const preview = getChunkPreview(options.content);
const details = [
`Federated chunk execution failed.`,
`chunk: ${options.chunkName}`,
`source: ${options.source}`,
`location: ${options.location}`
];
if (options.hostName) details.push(`host: ${options.hostName}`);
if (options.resolution) {
details.push(`resolved-from: ${options.resolution.resolvedFrom}`);
if (options.resolution.remoteName) details.push(`remote: ${options.resolution.remoteName}`);
if (options.resolution.publicPath) details.push(`public-path: ${options.resolution.publicPath}`);
if (options.resolution.rootOutputDir) details.push(`root-output-dir: ${options.resolution.rootOutputDir}`);
if (options.resolution.remoteEntryUrl) details.push(`remote-entry: ${options.resolution.remoteEntryUrl}`);
}
if (preview) details.push(`preview: ${preview}`);
normalizedError.message = `${normalizedError.message}\n${details.join("\n")}`;
Object.assign(normalizedError, {
chunkName: options.chunkName,
chunkLocation: options.location,
chunkSource: options.source,
chunkPreview: preview,
chunkHostName: options.hostName,
chunkResolution: options.resolution
});
return normalizedError;
};
function importNodeModule(name) {
if (!name) throw new Error("import specifier is required");
if (nodeRuntimeImportCache.has(name)) return nodeRuntimeImportCache.get(name);
const promise = new Function("name", `return import(name)`)(name).then((res) => res.default).catch((error) => {
console.error(`Error importing module ${name}:`, error);
nodeRuntimeImportCache.delete(name);
throw error;
});
nodeRuntimeImportCache.set(name, promise);
return promise;
}
const resolveFile = (rootOutputDir, chunkId) => {
return __non_webpack_require__("path").join(__dirname, rootOutputDir + __webpack_require__.u(chunkId));
};
const returnFromCache = (remoteName) => {
const federationInstances = new Function("return globalThis")()["__FEDERATION__"]["__INSTANCES__"];
for (const instance of federationInstances) {
const moduleContainer = instance.moduleCache.get(remoteName);
if (moduleContainer?.remoteInfo) return moduleContainer.remoteInfo.entry;
}
return null;
};
const returnFromGlobalInstances = (remoteName) => {
const federationInstances = new Function("return globalThis")()["__FEDERATION__"]["__INSTANCES__"];
for (const instance of federationInstances) for (const remote of instance.options.remotes) if (remote.name === remoteName || remote.alias === remoteName) {
console.log("Backup remote entry found:", remote.entry);
return remote.entry;
}
return null;
};
const loadFromFs = (filename, callback) => {
const fs = __non_webpack_require__("fs");
const path = __non_webpack_require__("path");
const vm = __non_webpack_require__("vm");
if (fs.existsSync(filename)) fs.readFile(filename, "utf-8", (err, content) => {
if (err) return callback(err, null);
const chunk = {};
try {
new vm.Script(`(function(exports, require, __dirname, __filename) {${content}\n})`, {
filename,
importModuleDynamically: vm.constants?.USE_MAIN_CONTEXT_DEFAULT_LOADER ?? importNodeModule
}).runInThisContext()(chunk, __non_webpack_require__, path.dirname(filename), filename);
callback(null, chunk);
} catch (e) {
callback(enrichChunkExecutionError(e, {
chunkName: path.basename(filename),
location: filename,
source: "filesystem",
content
}), null);
}
});
else callback(/* @__PURE__ */ new Error(`File ${filename} does not exist`), null);
};
const fetchAndRun = (url, chunkName, callback, args) => {
(typeof fetch === "undefined" ? importNodeModule("node-fetch").then((mod) => mod.default) : Promise.resolve(fetch)).then((fetchFunction) => {
return args.origin.loaderHook.lifecycle.fetch.emit(url.href, {}).then((res) => {
if (!res || !(res instanceof Response)) return fetchFunction(url.href).then((response) => response.text());
return res.text();
});
}).then((data) => {
const chunk = {};
const hostName = args?.origin?.options?.name || args?.origin?.name;
const resolution = url.mfMetadata;
try {
eval(`(function(exports, require, __dirname, __filename) {${data}\n})`)(chunk, __non_webpack_require__, url.pathname.split("/").slice(0, -1).join("/"), chunkName);
callback(null, chunk);
} catch (e) {
callback(enrichChunkExecutionError(e, {
chunkName,
location: url.href,
source: "remote-url",
content: data,
hostName,
resolution
}), null);
}
}).catch((err) => callback(err, null));
};
const resolveUrl = (remoteName, chunkName) => {
try {
return Object.assign(new URL(chunkName, __webpack_require__.p), { mfMetadata: {
chunkName,
publicPath: __webpack_require__.p,
remoteName,
rootOutputDir: __webpack_require__.federation.rootOutputDir || "",
resolvedFrom: "public-path"
} });
} catch {
const entryUrl = returnFromCache(remoteName) || returnFromGlobalInstances(remoteName);
if (!entryUrl) return null;
const url = new URL(entryUrl);
const path = __non_webpack_require__("path");
const urlPath = url.pathname;
const lastSlashIndex = urlPath.lastIndexOf("/");
const directoryPath = lastSlashIndex >= 0 ? urlPath.substring(0, lastSlashIndex + 1) : "/";
const rootDir = __webpack_require__.federation.rootOutputDir || "";
const combinedPath = path.join(directoryPath, rootDir, chunkName).replace(/\\/g, "/");
return Object.assign(new URL(combinedPath, url.origin), { mfMetadata: {
chunkName,
publicPath: __webpack_require__.p,
remoteName,
rootOutputDir: rootDir,
resolvedFrom: "remote-entry-fallback",
remoteEntryUrl: entryUrl
} });
}
};
const loadChunk = (strategy, chunkId, rootOutputDir, callback, args) => {
if (strategy === "filesystem") return loadFromFs(resolveFile(rootOutputDir, chunkId), callback);
const url = resolveUrl(rootOutputDir, chunkId);
if (!url) return callback(null, {
modules: {},
ids: [],
runtime: null
});
fetchAndRun(url, chunkId, callback, args);
};
const installChunk = (chunk, installedChunks) => {
for (const moduleId in chunk.modules) __webpack_require__.m[moduleId] = chunk.modules[moduleId];
if (chunk.runtime) chunk.runtime(__webpack_require__);
for (const chunkId of chunk.ids) {
if (installedChunks[chunkId]) installedChunks[chunkId][0]();
installedChunks[chunkId] = 0;
}
};
const deleteChunk = (chunkId, installedChunks) => {
delete installedChunks[chunkId];
return true;
};
const setupScriptLoader = () => {
__webpack_require__.l = (url, done, key, chunkId) => {
if (!key || chunkId) throw new Error(`__webpack_require__.l name is required for ${url}`);
__webpack_require__.federation.runtime.loadScriptNode(url, { attrs: { globalName: key } }).then((res) => {
const enhancedRemote = __webpack_require__.federation.instance.initRawContainer(key, url, res);
new Function("return globalThis")()[key] = enhancedRemote;
done(enhancedRemote);
}).catch(done);
};
};
const setupChunkHandler = (installedChunks, args) => {
return (chunkId, promises) => {
let installedChunkData = installedChunks[chunkId];
if (installedChunkData !== 0) if (installedChunkData) promises.push(installedChunkData[2]);
else if (__webpack_require__.federation.chunkMatcher ? __webpack_require__.federation.chunkMatcher(chunkId) : true) {
const promise = new Promise((resolve, reject) => {
installedChunkData = installedChunks[chunkId] = [resolve, reject];
const fs = typeof process !== "undefined" ? __non_webpack_require__("fs") : false;
const filename = typeof process !== "undefined" ? resolveFile(__webpack_require__.federation.rootOutputDir || "", chunkId) : false;
if (fs && fs.existsSync(filename)) loadChunk("filesystem", chunkId, __webpack_require__.federation.rootOutputDir || "", (err, chunk) => {
if (err) return deleteChunk(chunkId, installedChunks) && reject(err);
if (chunk) installChunk(chunk, installedChunks);
resolve(chunk);
}, args);
else {
const chunkName = __webpack_require__.u(chunkId);
loadChunk(typeof process === "undefined" ? "http-eval" : "http-vm", chunkName, __webpack_require__.federation.initOptions.name, (err, chunk) => {
if (err) return deleteChunk(chunkId, installedChunks) && reject(err);
if (chunk) installChunk(chunk, installedChunks);
resolve(chunk);
}, args);
}
});
promises.push(installedChunkData[2] = promise);
} else installedChunks[chunkId] = 0;
};
};
const setupWebpackRequirePatching = (handle) => {
if (__webpack_require__.f) {
if (__webpack_require__.f.require) {
console.warn("\x1B[33m%s\x1B[0m", "CAUTION: build target is not set to \"async-node\", attempting to patch additional chunk handlers. This may not work");
__webpack_require__.f.require = handle;
}
if (__webpack_require__.f.readFileVm) __webpack_require__.f.readFileVm = handle;
}
};
function runtimePlugin_default() {
return {
name: "node-federation-plugin",
beforeInit(args) {
(() => {
const installedChunks = {};
setupScriptLoader();
setupWebpackRequirePatching(setupChunkHandler(installedChunks, args));
})();
return args;
}
};
}
//#endregion
exports.default = runtimePlugin_default;
exports.deleteChunk = deleteChunk;
exports.fetchAndRun = fetchAndRun;
exports.importNodeModule = importNodeModule;
exports.installChunk = installChunk;
exports.loadChunk = loadChunk;
exports.loadFromFs = loadFromFs;
exports.nodeRuntimeImportCache = nodeRuntimeImportCache;
exports.resolveFile = resolveFile;
exports.resolveUrl = resolveUrl;
exports.returnFromCache = returnFromCache;
exports.returnFromGlobalInstances = returnFromGlobalInstances;
exports.setupChunkHandler = setupChunkHandler;
exports.setupScriptLoader = setupScriptLoader;
exports.setupWebpackRequirePatching = setupWebpackRequirePatching;
//# sourceMappingURL=runtimePlugin.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,226 @@
//#region src/runtimePlugin.ts
const nodeRuntimeImportCache = /* @__PURE__ */ new Map();
const CHUNK_PREVIEW_LENGTH = 240;
const getChunkPreview = (content) => content.slice(0, CHUNK_PREVIEW_LENGTH).replace(/\s+/g, " ").trim();
const enrichChunkExecutionError = (error, options) => {
const normalizedError = error instanceof Error ? error : new Error(String(error));
const preview = getChunkPreview(options.content);
const details = [
`Federated chunk execution failed.`,
`chunk: ${options.chunkName}`,
`source: ${options.source}`,
`location: ${options.location}`
];
if (options.hostName) details.push(`host: ${options.hostName}`);
if (options.resolution) {
details.push(`resolved-from: ${options.resolution.resolvedFrom}`);
if (options.resolution.remoteName) details.push(`remote: ${options.resolution.remoteName}`);
if (options.resolution.publicPath) details.push(`public-path: ${options.resolution.publicPath}`);
if (options.resolution.rootOutputDir) details.push(`root-output-dir: ${options.resolution.rootOutputDir}`);
if (options.resolution.remoteEntryUrl) details.push(`remote-entry: ${options.resolution.remoteEntryUrl}`);
}
if (preview) details.push(`preview: ${preview}`);
normalizedError.message = `${normalizedError.message}\n${details.join("\n")}`;
Object.assign(normalizedError, {
chunkName: options.chunkName,
chunkLocation: options.location,
chunkSource: options.source,
chunkPreview: preview,
chunkHostName: options.hostName,
chunkResolution: options.resolution
});
return normalizedError;
};
function importNodeModule(name) {
if (!name) throw new Error("import specifier is required");
if (nodeRuntimeImportCache.has(name)) return nodeRuntimeImportCache.get(name);
const promise = new Function("name", `return import(name)`)(name).then((res) => res.default).catch((error) => {
console.error(`Error importing module ${name}:`, error);
nodeRuntimeImportCache.delete(name);
throw error;
});
nodeRuntimeImportCache.set(name, promise);
return promise;
}
const resolveFile = (rootOutputDir, chunkId) => {
return __non_webpack_require__("path").join(__dirname, rootOutputDir + __webpack_require__.u(chunkId));
};
const returnFromCache = (remoteName) => {
const federationInstances = new Function("return globalThis")()["__FEDERATION__"]["__INSTANCES__"];
for (const instance of federationInstances) {
const moduleContainer = instance.moduleCache.get(remoteName);
if (moduleContainer?.remoteInfo) return moduleContainer.remoteInfo.entry;
}
return null;
};
const returnFromGlobalInstances = (remoteName) => {
const federationInstances = new Function("return globalThis")()["__FEDERATION__"]["__INSTANCES__"];
for (const instance of federationInstances) for (const remote of instance.options.remotes) if (remote.name === remoteName || remote.alias === remoteName) {
console.log("Backup remote entry found:", remote.entry);
return remote.entry;
}
return null;
};
const loadFromFs = (filename, callback) => {
const fs = __non_webpack_require__("fs");
const path = __non_webpack_require__("path");
const vm = __non_webpack_require__("vm");
if (fs.existsSync(filename)) fs.readFile(filename, "utf-8", (err, content) => {
if (err) return callback(err, null);
const chunk = {};
try {
new vm.Script(`(function(exports, require, __dirname, __filename) {${content}\n})`, {
filename,
importModuleDynamically: vm.constants?.USE_MAIN_CONTEXT_DEFAULT_LOADER ?? importNodeModule
}).runInThisContext()(chunk, __non_webpack_require__, path.dirname(filename), filename);
callback(null, chunk);
} catch (e) {
callback(enrichChunkExecutionError(e, {
chunkName: path.basename(filename),
location: filename,
source: "filesystem",
content
}), null);
}
});
else callback(/* @__PURE__ */ new Error(`File ${filename} does not exist`), null);
};
const fetchAndRun = (url, chunkName, callback, args) => {
(typeof fetch === "undefined" ? importNodeModule("node-fetch").then((mod) => mod.default) : Promise.resolve(fetch)).then((fetchFunction) => {
return args.origin.loaderHook.lifecycle.fetch.emit(url.href, {}).then((res) => {
if (!res || !(res instanceof Response)) return fetchFunction(url.href).then((response) => response.text());
return res.text();
});
}).then((data) => {
const chunk = {};
const hostName = args?.origin?.options?.name || args?.origin?.name;
const resolution = url.mfMetadata;
try {
eval(`(function(exports, require, __dirname, __filename) {${data}\n})`)(chunk, __non_webpack_require__, url.pathname.split("/").slice(0, -1).join("/"), chunkName);
callback(null, chunk);
} catch (e) {
callback(enrichChunkExecutionError(e, {
chunkName,
location: url.href,
source: "remote-url",
content: data,
hostName,
resolution
}), null);
}
}).catch((err) => callback(err, null));
};
const resolveUrl = (remoteName, chunkName) => {
try {
return Object.assign(new URL(chunkName, __webpack_require__.p), { mfMetadata: {
chunkName,
publicPath: __webpack_require__.p,
remoteName,
rootOutputDir: __webpack_require__.federation.rootOutputDir || "",
resolvedFrom: "public-path"
} });
} catch {
const entryUrl = returnFromCache(remoteName) || returnFromGlobalInstances(remoteName);
if (!entryUrl) return null;
const url = new URL(entryUrl);
const path = __non_webpack_require__("path");
const urlPath = url.pathname;
const lastSlashIndex = urlPath.lastIndexOf("/");
const directoryPath = lastSlashIndex >= 0 ? urlPath.substring(0, lastSlashIndex + 1) : "/";
const rootDir = __webpack_require__.federation.rootOutputDir || "";
const combinedPath = path.join(directoryPath, rootDir, chunkName).replace(/\\/g, "/");
return Object.assign(new URL(combinedPath, url.origin), { mfMetadata: {
chunkName,
publicPath: __webpack_require__.p,
remoteName,
rootOutputDir: rootDir,
resolvedFrom: "remote-entry-fallback",
remoteEntryUrl: entryUrl
} });
}
};
const loadChunk = (strategy, chunkId, rootOutputDir, callback, args) => {
if (strategy === "filesystem") return loadFromFs(resolveFile(rootOutputDir, chunkId), callback);
const url = resolveUrl(rootOutputDir, chunkId);
if (!url) return callback(null, {
modules: {},
ids: [],
runtime: null
});
fetchAndRun(url, chunkId, callback, args);
};
const installChunk = (chunk, installedChunks) => {
for (const moduleId in chunk.modules) __webpack_require__.m[moduleId] = chunk.modules[moduleId];
if (chunk.runtime) chunk.runtime(__webpack_require__);
for (const chunkId of chunk.ids) {
if (installedChunks[chunkId]) installedChunks[chunkId][0]();
installedChunks[chunkId] = 0;
}
};
const deleteChunk = (chunkId, installedChunks) => {
delete installedChunks[chunkId];
return true;
};
const setupScriptLoader = () => {
__webpack_require__.l = (url, done, key, chunkId) => {
if (!key || chunkId) throw new Error(`__webpack_require__.l name is required for ${url}`);
__webpack_require__.federation.runtime.loadScriptNode(url, { attrs: { globalName: key } }).then((res) => {
const enhancedRemote = __webpack_require__.federation.instance.initRawContainer(key, url, res);
new Function("return globalThis")()[key] = enhancedRemote;
done(enhancedRemote);
}).catch(done);
};
};
const setupChunkHandler = (installedChunks, args) => {
return (chunkId, promises) => {
let installedChunkData = installedChunks[chunkId];
if (installedChunkData !== 0) if (installedChunkData) promises.push(installedChunkData[2]);
else if (__webpack_require__.federation.chunkMatcher ? __webpack_require__.federation.chunkMatcher(chunkId) : true) {
const promise = new Promise((resolve, reject) => {
installedChunkData = installedChunks[chunkId] = [resolve, reject];
const fs = typeof process !== "undefined" ? __non_webpack_require__("fs") : false;
const filename = typeof process !== "undefined" ? resolveFile(__webpack_require__.federation.rootOutputDir || "", chunkId) : false;
if (fs && fs.existsSync(filename)) loadChunk("filesystem", chunkId, __webpack_require__.federation.rootOutputDir || "", (err, chunk) => {
if (err) return deleteChunk(chunkId, installedChunks) && reject(err);
if (chunk) installChunk(chunk, installedChunks);
resolve(chunk);
}, args);
else {
const chunkName = __webpack_require__.u(chunkId);
loadChunk(typeof process === "undefined" ? "http-eval" : "http-vm", chunkName, __webpack_require__.federation.initOptions.name, (err, chunk) => {
if (err) return deleteChunk(chunkId, installedChunks) && reject(err);
if (chunk) installChunk(chunk, installedChunks);
resolve(chunk);
}, args);
}
});
promises.push(installedChunkData[2] = promise);
} else installedChunks[chunkId] = 0;
};
};
const setupWebpackRequirePatching = (handle) => {
if (__webpack_require__.f) {
if (__webpack_require__.f.require) {
console.warn("\x1B[33m%s\x1B[0m", "CAUTION: build target is not set to \"async-node\", attempting to patch additional chunk handlers. This may not work");
__webpack_require__.f.require = handle;
}
if (__webpack_require__.f.readFileVm) __webpack_require__.f.readFileVm = handle;
}
};
function runtimePlugin_default() {
return {
name: "node-federation-plugin",
beforeInit(args) {
(() => {
const installedChunks = {};
setupScriptLoader();
setupWebpackRequirePatching(setupChunkHandler(installedChunks, args));
})();
return args;
}
};
}
//#endregion
export { runtimePlugin_default as default, deleteChunk, fetchAndRun, importNodeModule, installChunk, loadChunk, loadFromFs, nodeRuntimeImportCache, resolveFile, resolveUrl, returnFromCache, returnFromGlobalInstances, setupChunkHandler, setupScriptLoader, setupWebpackRequirePatching };
//# sourceMappingURL=runtimePlugin.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,8 @@
import { moduleFederationPlugin } from "@module-federation/sdk";
//#region src/types/index.d.ts
type ModuleFederationPluginOptions = moduleFederationPlugin.ModuleFederationPluginOptions;
type RemotesObject = ModuleFederationPluginOptions['remotes'];
//#endregion
export { ModuleFederationPluginOptions, RemotesObject };
//# sourceMappingURL=index.d.mts.map

View File

@@ -0,0 +1,8 @@
import { moduleFederationPlugin } from "@module-federation/sdk";
//#region src/types/index.d.ts
type ModuleFederationPluginOptions = moduleFederationPlugin.ModuleFederationPluginOptions;
type RemotesObject = ModuleFederationPluginOptions['remotes'];
//#endregion
export { ModuleFederationPluginOptions, RemotesObject };
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1 @@
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });

View File

@@ -0,0 +1 @@
export { };

View File

@@ -0,0 +1,15 @@
//#region src/utils/flush-chunks.d.ts
/**
* Initialize usedChunks and share it globally.
* @type {Set}
*/
declare const usedChunks: any;
declare const getAllKnownRemotes: () => {};
/**
* Flush the chunks and return a deduplicated array of chunks.
* @returns {Promise<Array>} A promise that resolves to an array of deduplicated chunks.
*/
declare const flushChunks: () => Promise<unknown[]>;
//#endregion
export { flushChunks, getAllKnownRemotes, usedChunks };
//# sourceMappingURL=flush-chunks.d.mts.map

View File

@@ -0,0 +1,15 @@
//#region src/utils/flush-chunks.d.ts
/**
* Initialize usedChunks and share it globally.
* @type {Set}
*/
declare const usedChunks: any;
declare const getAllKnownRemotes: () => {};
/**
* Flush the chunks and return a deduplicated array of chunks.
* @returns {Promise<Array>} A promise that resolves to an array of deduplicated chunks.
*/
declare const flushChunks: () => Promise<unknown[]>;
//#endregion
export { flushChunks, getAllKnownRemotes, usedChunks };
//# sourceMappingURL=flush-chunks.d.ts.map

Some files were not shown because too many files have changed in this diff Show More