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

21
node_modules/@module-federation/node/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 ScriptedAlchemy LLC (Zack Jackson) Zhou Shaw (zhouxiao)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

235
node_modules/@module-federation/node/README.md generated vendored Normal file
View File

@@ -0,0 +1,235 @@
<p align="center">
<img src="https://github.com/module-federation/nextjs-mf/blob/main/packages/node/assets/banner.png" width="800"/>
</p>
<div align="center">
<!-- for version -->
<img src="https://img.shields.io/npm/v/@module-federation/node" alt="version" >
<img src="https://img.shields.io/npm/l/@module-federation/node.svg?" alt="license" >
<!-- for downloads -->
<img src="https://img.shields.io/npm/dt/@module-federation/node" alt="downloads">
</div>
<p align="center">
<strong>A package to bring the concept and power of module federation to NodeJS.</strong>
</p>
## ⚡ Features
- Exposes two Webpack Plugins to enable Module Federation.
- Can exported as UniversalFederationPlugin or NodeFederationPlugin with StreamingTargetPlugin
- Allows server to fetch chunks across the network.
- Allow distributed deployments of federated applications.
## 📦 Installation
To install the plugin run one of the following commands in your terminal for your application.
```bash
# npm
npm install @module-federation/node
# yarn
yarn add @module-federation/node
```
## 🚀 Usage
There are two approaches to using the plugins exported from this package, dependent on your use case.
### Use as Runtime Plugin
`module-federation/enhanced` supports runtime plugins.
```js
const { ModuleFederationPlugin } = require('@module-federation/enhanced');
const options = {
target: 'async-node',
output: {
chunkFilename: '[id]-[contenthash].js', // important to hash chunks
},
plugins: [
new ModuleFederationPlugin({
name: 'app1',
exposes: {},
remotes: {
app2: 'app2@http://',
},
runtimePlugins: [require.resolve('@module-federation/node/runtimePlugin')],
remoteType: 'script',
library: { type: 'commonjs-module', name: 'app1' },
}),
],
};
```
or you can enable it with some presets via UniversalFederation
```js
new UniversalFederationPlugin({
name: 'website2',
library: { type: 'commonjs-module' },
isServer: true, // or false
remotes: {},
filename: 'remoteEntry.js',
useRuntimePlugin: true, // uses the module-federation/enhanced runtime plugin api
exposes: {
'./SharedComponent': './remoteServer/SharedComponent',
},
});
```
### UniversalFederationPlugin
This plugin is an abstraction over both `NodeFederationPlugin` and `ModuleFederationPlugin`. It will alternate between which it uses based on where the build is intended to be used.
If the build is intended to be used on the `browser`, it will use the standard `ModuleFederationPlugin` and bundle your code accordingly, however, if it is intended for `server` usage, it will use `NodeFederationPlugin` to create the bundle.
This simplifies the code required in your `webpack.config.js` to enable SSR Module Federation. It determines which platform it needs to build for based on two things:
1. If the options passed to the plugin has specified `isServer: true`
2. If the name assigned to the config being used is `server`
It accepts the other standard options from `ModuleFederationPlugin` as well. You can see an example usage below:
```js
const { UniversalFederationPlugin } = require('@module-federation/node');
const config = {
target: isServer ? false : 'web',
plugins: [
new UniversalFederationPlugin({
name: 'website2',
library: { type: 'commonjs-module' },
isServer: true, // or false
remotes: {},
filename: 'remoteEntry.js',
useRuntimePlugin: true, // uses the module-federation/enhanced runtime plugins
exposes: {
'./SharedComponent': './remoteServer/SharedComponent',
},
}),
],
};
```
### NodeFederationPlugin and StreamingTargetPlugin
You can also use each of the underlying plugins individually if you need more control over when they are used.
At build time, you need to be aware if you're building for the `server` or for the `browser`.
If it's building for server, we need to set `target: false` to allow the plugins to function correctly.
The `NodeFederationPlugin` follows the same API as the [Module Federation Plugin](https://webpack.js.org/plugins/module-federation-plugin) and therefore should be a drop-in replacement if you already have it set up in your `webpack.config.js`.
### 🔧 Config Example
An example configuration is presented below:
```js
const { NodeFederationPlugin, StreamingTargetPlugin } = require('@module-federation/node');
const config = {
target: isServer ? false : 'web',
plugins: [
new NodeFederationPlugin({
name: 'website2',
library: { type: 'commonjs-module' },
remotes: {},
filename: 'remoteEntry.js',
exposes: {
'./SharedComponent': './remoteServer/SharedComponent',
},
}),
new StreamingTargetPlugin({
name: 'website2',
library: { type: 'commonjs-module' },
remotes: {},
}),
],
};
```
## Utilities
This package also exposes a few utilities to help with the setup of your federated application.
### revalidate
Used to "hot reload" the federated application.
- This is useful when you're developing your federated application and want to see changes without having to restart the server.
- Also useful for production environments where you want to be able to update the federated application without having to restart the server.
```js
import { revalidate } from '@module-federation/node/utils';
// we automatically reset require cache, so the reload callback is only if you need to do something else
revalidate().then((shouldReload) => {
// do something extra after revalidation
if (shouldReload) {
// reload the server
}
});
```
_Note_: To ensure that changes made to files in remotes are picked up `revalidate`, you can set the remotes webpack [output.filename](https://webpack.js.org/configuration/output/#outputfilename) to `[name]-[contenthash].js` (or similar). This will cause the remoteEntry.js file to be regenerated with a unique hash every time a new build occurs. The revalidate method intelligently detects changes by comparing the hashes of the remoteEntry.js files. By incorporating [contenthash] into the remote's webpack configuration, you enable the shell to seamlessly incorporate the updated files from the remotes.
**Hot reloading Express.js**
Express has its own route stack, so reloading require cache will not be enough to reload the routes inside express.
```js
//express.js
const app = express();
global.clearRoutes = () => {
app._router.stack = app._router.stack.filter((k) => !(k && k.route && k.route.path));
};
// in some other file (within the scope of webpack build)
// wherever you have your revalidation logic
revalidate().then((shouldReload) => {
if (shouldReload) {
global.clearRoutes();
}
});
```
### Overriding default http chunk fetch
```js
const chunkFetcher = globalThis.webpackChunkLoad || globalThis.fetch || fetchPolyfill;
// then it will pass one argument to the function, the url to fetch
chunkFetcher(url)
.then((res) => res.text())
.then((text) => {
// do something with the text
});
```
If you want to use your own custom fetch, or add fetch headers, either in the entrypoint of webpack or outside of webpack scope, like in express server you can override the default chunk fetcher by setting the `globalThis.webpackChunkLoad` variable.
```js
globalThis.webpackChunkLoad = async (url) => {
const res = await fetch(url, {
headers: {
'x-custom-header': 'custom-header-value',
},
});
return res.text();
};
```
## 🔑 License
- MIT @[ScriptedAlchemy](https://github.com/ScriptedAlchemy)
## 👨‍💻 Contributors
List of our amazing contributors 💥
<a href="https://github.com/module-federation/nextjs-mf/graphs/contributors">
<img src="https://contrib.rocks/image?repo=module-federation/node" />
</a>

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 { };

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