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/manifest/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024-present hanric(2heal1)
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.

34
node_modules/@module-federation/manifest/README.md generated vendored Normal file
View File

@@ -0,0 +1,34 @@
# `@module-federation/manifest` Documentation
## Description
This package contains the manifest plugin for webpack/rspack internal.
## Installation
```sh
npm install @module-federation/manifest
```
## Usage
1. replace expose options with container.options.exposes = containerManager.containerPluginExposesOptions;
```js
import { ContainerManager } from '@module-federation/managers';
const containerManager = new ContainerManager();
containerManager.init(options);
// it will set expose name automatically
options.exposes = containerManager.containerPluginExposesOptions;
```
2. use StatsPlugin in webpack.config.js
```js
import { StatsPlugin } from '@module-federation/manifest';
new StatsPlugin(mfOptions, {
pluginVersion: pkg.version,
bundler: 'webpack',
}).apply(compiler);
```

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

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024-present hanric(2heal1)
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.

View File

@@ -0,0 +1,18 @@
import { Stats, Manifest, moduleFederationPlugin } from '@module-federation/sdk';
import type { Compilation, Compiler } from 'webpack';
interface GenerateManifestOptions {
compilation: Compilation;
stats: Stats;
publicPath: string;
compiler: Compiler;
bundler: 'webpack' | 'rspack';
additionalData?: moduleFederationPlugin.PluginManifestOptions['additionalData'];
}
declare class ManifestManager {
private _options;
init(options: moduleFederationPlugin.ModuleFederationPluginOptions): void;
get fileName(): string;
updateManifest(options: GenerateManifestOptions): Manifest;
generateManifest(options: GenerateManifestOptions): Manifest;
}
export { ManifestManager };

View File

@@ -0,0 +1,160 @@
"use strict";
const __rslib_import_meta_url__ = /*#__PURE__*/ (function () {
return typeof document === 'undefined'
? new (require('url'.replace('', '')).URL)('file:' + __filename).href
: (document.currentScript && document.currentScript.src) ||
new URL('main.js', document.baseURI).href;
})();
;
// The require scope
var __webpack_require__ = {};
/************************************************************************/
// webpack/runtime/compat_get_default_export
(() => {
// getDefaultExport function for compatibility with non-ESM modules
__webpack_require__.n = (module) => {
var getter = module && module.__esModule ?
() => (module['default']) :
() => (module);
__webpack_require__.d(getter, { a: getter });
return getter;
};
})();
// webpack/runtime/define_property_getters
(() => {
__webpack_require__.d = (exports, definition) => {
for(var key in definition) {
if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
}
}
};
})();
// webpack/runtime/has_own_property
(() => {
__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
})();
// webpack/runtime/make_namespace_object
(() => {
// define __esModule on exports
__webpack_require__.r = (exports) => {
if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
}
Object.defineProperty(exports, '__esModule', { value: true });
};
})();
/************************************************************************/
var __webpack_exports__ = {};
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
ManifestManager: () => (/* binding */ ManifestManager)
});
;// CONCATENATED MODULE: external "node:util"
const external_node_util_namespaceObject = require("node:util");
;// CONCATENATED MODULE: external "@module-federation/sdk"
const sdk_namespaceObject = require("@module-federation/sdk");
;// CONCATENATED MODULE: external "./utils.js"
const external_utils_js_namespaceObject = require("./utils.js");
;// CONCATENATED MODULE: external "./logger.js"
const external_logger_js_namespaceObject = require("./logger.js");
var external_logger_js_default = /*#__PURE__*/__webpack_require__.n(external_logger_js_namespaceObject);
;// CONCATENATED MODULE: ./src/ManifestManager.ts
class ManifestManager {
init(options) {
this._options = options;
}
get fileName() {
return (0,sdk_namespaceObject.getManifestFileName)(this._options.manifest).manifestFileName;
}
updateManifest(options) {
const manifest = this.generateManifest(options);
return manifest;
}
generateManifest(options) {
const { publicPath, stats, compiler } = options;
// Initialize manifest with required properties from stats
const { id, name, metaData } = stats;
if (metaData.buildInfo) {
'target' in metaData.buildInfo && delete metaData.buildInfo.target;
'plugins' in metaData.buildInfo && delete metaData.buildInfo.plugins;
}
const manifest = {
id,
name,
metaData,
shared: [],
remotes: [],
exposes: []
};
manifest.exposes = stats.exposes.reduce((sum, cur)=>{
const expose = {
id: cur.id,
name: cur.name,
assets: cur.assets,
path: cur.path
};
sum.push(expose);
return sum;
}, []);
manifest.shared = stats.shared.reduce((sum, cur)=>{
const shared = {
id: cur.id,
name: cur.name,
version: cur.version,
singleton: cur.singleton,
requiredVersion: cur.requiredVersion,
hash: cur.hash,
assets: cur.assets,
fallback: cur.fallback,
fallbackName: cur.fallbackName,
fallbackType: cur.fallbackType
};
sum.push(shared);
return sum;
}, []);
manifest.remotes = stats.remotes.reduce((sum, cur)=>{
// @ts-ignore version/entry will be added as follow
const remote = {
federationContainerName: cur.federationContainerName,
moduleName: cur.moduleName,
alias: cur.alias
};
if ('entry' in cur) {
// @ts-ignore
remote.entry = cur.entry;
} else if ('version' in cur) {
// @ts-ignore
remote.entry = cur.version;
}
sum.push(remote);
return sum;
}, []);
if ((0,external_utils_js_namespaceObject.isDev)() && (process.env['MF_SSR_PRJ'] ? compiler.options.target !== 'async-node' : true)) {
external_logger_js_default().info(`Manifest Link: ${(0,external_node_util_namespaceObject.styleText)('cyan', `${publicPath === 'auto' ? '{auto}/' : publicPath}${this.fileName}`)} `);
}
return manifest;
}
constructor(){
this._options = {};
}
}
exports.ManifestManager = __webpack_exports__.ManifestManager;
for(var __webpack_i__ in __webpack_exports__) {
if(["ManifestManager"].indexOf(__webpack_i__) === -1) {
exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
}
}
Object.defineProperty(exports, '__esModule', { value: true });

View File

@@ -0,0 +1,100 @@
import { styleText } from "node:util";
import { getManifestFileName } from "@module-federation/sdk";
import { isDev } from "./utils.mjs";
import logger from "./logger.mjs";
;// CONCATENATED MODULE: external "node:util"
;// CONCATENATED MODULE: external "@module-federation/sdk"
;// CONCATENATED MODULE: external "./utils.mjs"
;// CONCATENATED MODULE: external "./logger.mjs"
;// CONCATENATED MODULE: ./src/ManifestManager.ts
class ManifestManager {
init(options) {
this._options = options;
}
get fileName() {
return getManifestFileName(this._options.manifest).manifestFileName;
}
updateManifest(options) {
const manifest = this.generateManifest(options);
return manifest;
}
generateManifest(options) {
const { publicPath, stats, compiler } = options;
// Initialize manifest with required properties from stats
const { id, name, metaData } = stats;
if (metaData.buildInfo) {
'target' in metaData.buildInfo && delete metaData.buildInfo.target;
'plugins' in metaData.buildInfo && delete metaData.buildInfo.plugins;
}
const manifest = {
id,
name,
metaData,
shared: [],
remotes: [],
exposes: []
};
manifest.exposes = stats.exposes.reduce((sum, cur)=>{
const expose = {
id: cur.id,
name: cur.name,
assets: cur.assets,
path: cur.path
};
sum.push(expose);
return sum;
}, []);
manifest.shared = stats.shared.reduce((sum, cur)=>{
const shared = {
id: cur.id,
name: cur.name,
version: cur.version,
singleton: cur.singleton,
requiredVersion: cur.requiredVersion,
hash: cur.hash,
assets: cur.assets,
fallback: cur.fallback,
fallbackName: cur.fallbackName,
fallbackType: cur.fallbackType
};
sum.push(shared);
return sum;
}, []);
manifest.remotes = stats.remotes.reduce((sum, cur)=>{
// @ts-ignore version/entry will be added as follow
const remote = {
federationContainerName: cur.federationContainerName,
moduleName: cur.moduleName,
alias: cur.alias
};
if ('entry' in cur) {
// @ts-ignore
remote.entry = cur.entry;
} else if ('version' in cur) {
// @ts-ignore
remote.entry = cur.version;
}
sum.push(remote);
return sum;
}, []);
if (isDev() && (process.env['MF_SSR_PRJ'] ? compiler.options.target !== 'async-node' : true)) {
logger.info(`Manifest Link: ${styleText('cyan', `${publicPath === 'auto' ? '{auto}/' : publicPath}${this.fileName}`)} `);
}
return manifest;
}
constructor(){
this._options = {};
}
}
export { ManifestManager };

View File

@@ -0,0 +1,44 @@
import { StatsExpose, StatsRemote, StatsShared, moduleFederationPlugin } from '@module-federation/sdk';
import type { StatsModule } from '../../../webpack/lib/stats/DefaultStatsFactoryPlugin.d';
import type managerTypes from '@module-federation/managers';
export declare const getExposeName: (exposeKey: string) => string;
export declare function getExposeItem({ exposeKey, name, file, }: {
exposeKey: string;
name: string;
file: {
import: string[];
};
}): StatsExpose;
export declare const getShareItem: ({ pkgName, normalizedShareOptions, pkgVersion, hostName, }: {
pkgName: string;
hostName?: string;
normalizedShareOptions: managerTypes.types.NormalizedSharedOptions[string];
pkgVersion: string;
}) => StatsShared;
declare class ModuleHandler {
private _options;
private _bundler;
private _modules;
private _containerManager;
private _remoteManager;
private _sharedManager;
constructor(options: moduleFederationPlugin.ModuleFederationPluginOptions, modules: StatsModule[], { bundler }: {
bundler: 'webpack' | 'rspack';
});
get isRspack(): boolean;
private _handleSharedModule;
private _handleRemoteModule;
private _handleContainerModule;
private _getContainerExposeEntriesFromOptions;
private _initializeExposesFromOptions;
collect(): {
remotes: StatsRemote[];
exposesMap: {
[exposeImportValue: string]: StatsExpose;
};
sharedMap: {
[sharedKey: string]: StatsShared;
};
};
}
export { ModuleHandler };

View File

@@ -0,0 +1,512 @@
"use strict";
const __rslib_import_meta_url__ = /*#__PURE__*/ (function () {
return typeof document === 'undefined'
? new (require('url'.replace('', '')).URL)('file:' + __filename).href
: (document.currentScript && document.currentScript.src) ||
new URL('main.js', document.baseURI).href;
})();
;
// The require scope
var __webpack_require__ = {};
/************************************************************************/
// webpack/runtime/compat_get_default_export
(() => {
// getDefaultExport function for compatibility with non-ESM modules
__webpack_require__.n = (module) => {
var getter = module && module.__esModule ?
() => (module['default']) :
() => (module);
__webpack_require__.d(getter, { a: getter });
return getter;
};
})();
// webpack/runtime/define_property_getters
(() => {
__webpack_require__.d = (exports, definition) => {
for(var key in definition) {
if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
}
}
};
})();
// webpack/runtime/has_own_property
(() => {
__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
})();
// webpack/runtime/make_namespace_object
(() => {
// define __esModule on exports
__webpack_require__.r = (exports) => {
if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
}
Object.defineProperty(exports, '__esModule', { value: true });
};
})();
/************************************************************************/
var __webpack_exports__ = {};
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
getExposeItem: () => (/* binding */ getExposeItem),
ModuleHandler: () => (/* binding */ ModuleHandler),
getShareItem: () => (/* binding */ getShareItem),
getExposeName: () => (/* binding */ getExposeName)
});
;// CONCATENATED MODULE: external "@module-federation/sdk"
const sdk_namespaceObject = require("@module-federation/sdk");
;// CONCATENATED MODULE: external "path"
const external_path_namespaceObject = require("path");
var external_path_default = /*#__PURE__*/__webpack_require__.n(external_path_namespaceObject);
;// CONCATENATED MODULE: external "@module-federation/managers"
const managers_namespaceObject = require("@module-federation/managers");
;// CONCATENATED MODULE: external "./utils.js"
const external_utils_js_namespaceObject = require("./utils.js");
;// CONCATENATED MODULE: ./src/ModuleHandler.ts
const isNonEmptyString = (value)=>{
return typeof value === 'string' && value.trim().length > 0;
};
const normalizeExposeValue = (exposeValue)=>{
if (!exposeValue) {
return undefined;
}
const toImportArray = (value)=>{
if (isNonEmptyString(value)) {
return [
value
];
}
if (Array.isArray(value)) {
const normalized = value.filter(isNonEmptyString);
return normalized.length ? normalized : undefined;
}
return undefined;
};
if (typeof exposeValue === 'object') {
if ('import' in exposeValue) {
const { import: rawImport, name } = exposeValue;
const normalizedImport = toImportArray(rawImport);
if (!(normalizedImport === null || normalizedImport === void 0 ? void 0 : normalizedImport.length)) {
return undefined;
}
return {
import: normalizedImport,
...isNonEmptyString(name) ? {
name
} : {}
};
}
return undefined;
}
const normalizedImport = toImportArray(exposeValue);
if (!(normalizedImport === null || normalizedImport === void 0 ? void 0 : normalizedImport.length)) {
return undefined;
}
return {
import: normalizedImport
};
};
const parseContainerExposeEntries = (identifier)=>{
const startIndex = identifier.indexOf('[');
if (startIndex < 0) {
return undefined;
}
let depth = 0;
let inString = false;
let isEscaped = false;
for(let cursor = startIndex; cursor < identifier.length; cursor++){
const char = identifier[cursor];
if (isEscaped) {
isEscaped = false;
continue;
}
if (char === '\\') {
isEscaped = true;
continue;
}
if (char === '"') {
inString = !inString;
continue;
}
if (inString) {
continue;
}
if (char === '[') {
depth++;
} else if (char === ']') {
depth--;
if (depth === 0) {
const serialized = identifier.slice(startIndex, cursor + 1);
try {
return JSON.parse(serialized);
} catch {
return undefined;
}
}
}
}
return undefined;
};
const getExposeName = (exposeKey)=>{
return exposeKey.replace('./', '');
};
function getExposeItem({ exposeKey, name, file }) {
const exposeModuleName = getExposeName(exposeKey);
return {
path: exposeKey,
id: (0,sdk_namespaceObject.composeKeyWithSeparator)(name, exposeModuleName),
name: exposeModuleName,
// @ts-ignore to deduplicate
requires: [],
file: external_path_default().relative(process.cwd(), file.import[0]),
assets: {
js: {
async: [],
sync: []
},
css: {
async: [],
sync: []
}
}
};
}
const getShareItem = ({ pkgName, normalizedShareOptions, pkgVersion, hostName })=>{
return {
...normalizedShareOptions,
id: `${hostName}:${pkgName}`,
requiredVersion: (normalizedShareOptions === null || normalizedShareOptions === void 0 ? void 0 : normalizedShareOptions.requiredVersion) || `^${pkgVersion}`,
name: pkgName,
version: pkgVersion,
assets: {
js: {
async: [],
sync: []
},
css: {
async: [],
sync: []
}
},
// @ts-ignore to deduplicate
usedIn: new Set(),
usedExports: [],
fallback: ''
};
};
class ModuleHandler {
get isRspack() {
return this._bundler === 'rspack';
}
_handleSharedModule(mod, sharedMap, exposesMap) {
const { identifier, moduleType } = mod;
if (!identifier) {
return;
}
const sharedManagerNormalizedOptions = this._sharedManager.normalizedOptions;
const initShared = (pkgName, pkgVersion)=>{
if (sharedMap[pkgName]) {
return;
}
sharedMap[pkgName] = getShareItem({
pkgName,
pkgVersion,
normalizedShareOptions: sharedManagerNormalizedOptions[pkgName],
hostName: this._options.name
});
};
const collectRelationshipMap = (mod, pkgName)=>{
const { issuerName, reasons } = mod;
if (issuerName) {
if (exposesMap[(0,external_utils_js_namespaceObject.getFileNameWithOutExt)(issuerName)]) {
const expose = exposesMap[(0,external_utils_js_namespaceObject.getFileNameWithOutExt)(issuerName)];
// @ts-ignore use Set to deduplicate
expose.requires.push(pkgName);
// @ts-ignore use Set to deduplicate
sharedMap[pkgName].usedIn.add(expose.path);
}
}
if (reasons) {
reasons.forEach(({ resolvedModule, moduleName })=>{
let exposeModName = this.isRspack ? moduleName : resolvedModule;
// filters out entrypoints
if (exposeModName) {
if (exposesMap[(0,external_utils_js_namespaceObject.getFileNameWithOutExt)(exposeModName)]) {
const expose = exposesMap[(0,external_utils_js_namespaceObject.getFileNameWithOutExt)(exposeModName)];
// @ts-ignore to deduplicate
expose.requires.push(pkgName);
// @ts-ignore to deduplicate
sharedMap[pkgName].usedIn.add(expose.path);
}
}
});
}
};
const parseResolvedIdentifier = (nameAndVersion)=>{
let name = '';
let version = '';
if (nameAndVersion.startsWith('@')) {
const splitInfo = nameAndVersion.split('@');
splitInfo[0] = '@';
name = splitInfo[0] + splitInfo[1];
version = splitInfo[2];
} else if (nameAndVersion.includes('@')) {
[name, version] = nameAndVersion.split('@');
version = version.replace(/[\^~>|>=]/g, '');
}
return {
name,
version
};
};
if (moduleType === 'provide-module') {
// identifier(rspack) = provide shared module (default) react@18.2.0 = /temp/node_modules/.pnpm/react@18.2.0/node_modules/react/index.js
// identifier(webpack) = provide module (default) react@18.2.0 = /temp/node_modules/.pnpm/react@18.2.0/node_modules/react/index.js
const data = identifier.split(' ');
const nameAndVersion = this.isRspack ? data[4] : data[3];
const { name, version } = parseResolvedIdentifier(nameAndVersion);
if (name && version) {
initShared(name, version);
collectRelationshipMap(mod, name);
}
}
if (moduleType === 'consume-shared-module') {
// identifier(rspack) = consume shared module (default) lodash/get@^4.17.21 (strict) (fallback: /temp/node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/get.js)
// identifier(webpack) = consume-shared-module|default|react-dom|!=1.8...2...0|false|/temp/node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/index.js|true|false
const SEPARATOR = this.isRspack ? ' ' : '|';
const data = identifier.split(SEPARATOR);
let pkgName = '';
let pkgVersion = '';
if (this.isRspack) {
const nameAndVersion = data[4];
const res = parseResolvedIdentifier(nameAndVersion);
pkgName = res.name;
pkgVersion = res.version;
} else {
pkgName = data[2];
const pkgVersionRange = data[3];
pkgVersion = '';
if (pkgVersionRange.startsWith('=')) {
pkgVersion = data[3].replace('=', '');
} else {
if (sharedManagerNormalizedOptions[pkgName]) {
pkgVersion = sharedManagerNormalizedOptions[pkgName].version;
} else {
const fullPkgName = pkgName.split('/').slice(0, -1).join('/');
// pkgName: react-dom/
if (sharedManagerNormalizedOptions[`${fullPkgName}/`]) {
if (sharedManagerNormalizedOptions[fullPkgName]) {
pkgVersion = sharedManagerNormalizedOptions[fullPkgName].version;
} else {
pkgVersion = sharedManagerNormalizedOptions[`${fullPkgName}/`].version;
}
}
}
}
}
if (pkgName && pkgVersion) {
initShared(pkgName, pkgVersion);
collectRelationshipMap(mod, pkgName);
}
}
}
_handleRemoteModule(mod, remotes, remotesConsumerMap) {
const { identifier, reasons, nameForCondition } = mod;
if (!identifier) {
return;
}
const remoteManagerNormalizedOptions = this._remoteManager.normalizedOptions;
// identifier = remote (default) webpack/container/reference/app2 ./Button
const data = identifier.split(' ');
if (data.length === 4) {
const moduleName = data[3].replace('./', '');
const remoteAlias = data[2].replace('webpack/container/reference/', '');
const normalizedRemote = remoteManagerNormalizedOptions[remoteAlias];
const basicRemote = {
alias: normalizedRemote.alias,
consumingFederationContainerName: this._options.name || '',
federationContainerName: remoteManagerNormalizedOptions[remoteAlias].name,
moduleName,
// @ts-ignore to deduplicate
usedIn: new Set()
};
if (!nameForCondition) {
return;
}
let remote;
if ('version' in normalizedRemote) {
remote = {
...basicRemote,
version: normalizedRemote.version
};
} else {
remote = {
...basicRemote,
entry: normalizedRemote.entry
};
}
remotes.push(remote);
remotesConsumerMap[nameForCondition] = remote;
}
if (reasons) {
reasons.forEach(({ userRequest, resolvedModule, moduleName })=>{
let exposeModName = this.isRspack ? moduleName : resolvedModule;
if (userRequest && exposeModName && remotesConsumerMap[userRequest]) {
// @ts-ignore to deduplicate
remotesConsumerMap[userRequest].usedIn.add(exposeModName.replace('./', ''));
}
});
}
}
_handleContainerModule(mod, exposesMap) {
const { identifier } = mod;
if (!identifier) {
return;
}
// identifier: container entry (default) [[".",{"import":["./src/routes/page.tsx"],"name":"__federation_expose_default_export"}]]'
const entries = parseContainerExposeEntries(identifier) ?? this._getContainerExposeEntriesFromOptions();
if (!entries) {
return;
}
entries.forEach(([prefixedName, file])=>{
// TODO: support multiple import
exposesMap[(0,external_utils_js_namespaceObject.getFileNameWithOutExt)(file.import[0])] = getExposeItem({
exposeKey: prefixedName,
name: this._options.name,
file
});
});
}
_getContainerExposeEntriesFromOptions() {
const exposes = this._containerManager.containerPluginExposesOptions;
const normalizedEntries = Object.entries(exposes).reduce((acc, [exposeKey, exposeOptions])=>{
const normalizedExpose = normalizeExposeValue(exposeOptions);
if (!(normalizedExpose === null || normalizedExpose === void 0 ? void 0 : normalizedExpose.import.length)) {
return acc;
}
acc.push([
exposeKey,
normalizedExpose
]);
return acc;
}, []);
if (normalizedEntries.length) {
return normalizedEntries;
}
const rawExposes = this._options.exposes;
if (!rawExposes || Array.isArray(rawExposes)) {
return undefined;
}
const normalizedFromOptions = Object.entries(rawExposes).reduce((acc, [exposeKey, exposeOptions])=>{
const normalizedExpose = normalizeExposeValue(exposeOptions);
if (!(normalizedExpose === null || normalizedExpose === void 0 ? void 0 : normalizedExpose.import.length)) {
return acc;
}
acc.push([
exposeKey,
normalizedExpose
]);
return acc;
}, []);
return normalizedFromOptions.length ? normalizedFromOptions : undefined;
}
_initializeExposesFromOptions(exposesMap) {
if (!this._options.name || !this._containerManager.enable) {
return;
}
const exposes = this._containerManager.containerPluginExposesOptions;
Object.entries(exposes).forEach(([exposeKey, exposeOptions])=>{
var _exposeOptions_import;
if (!((_exposeOptions_import = exposeOptions.import) === null || _exposeOptions_import === void 0 ? void 0 : _exposeOptions_import.length)) {
return;
}
const [exposeImport] = exposeOptions.import;
if (!exposeImport) {
return;
}
const exposeMapKey = (0,external_utils_js_namespaceObject.getFileNameWithOutExt)(exposeImport);
if (!exposesMap[exposeMapKey]) {
exposesMap[exposeMapKey] = getExposeItem({
exposeKey,
name: this._options.name,
file: exposeOptions
});
}
});
}
collect() {
const remotes = [];
const remotesConsumerMap = {};
const exposesMap = {};
const sharedMap = {};
this._initializeExposesFromOptions(exposesMap);
const isSharedModule = (moduleType)=>{
return Boolean(moduleType && [
'provide-module',
'consume-shared-module'
].includes(moduleType));
};
const isContainerModule = (identifier)=>{
return identifier.startsWith('container entry');
};
const isRemoteModule = (identifier)=>{
return identifier.startsWith('remote ');
};
// handle remote/expose
this._modules.forEach((mod)=>{
const { identifier, reasons, nameForCondition, moduleType } = mod;
if (!identifier) {
return;
}
if (isSharedModule(moduleType)) {
this._handleSharedModule(mod, sharedMap, exposesMap);
}
if (isRemoteModule(identifier)) {
this._handleRemoteModule(mod, remotes, remotesConsumerMap);
} else if (isContainerModule(identifier)) {
this._handleContainerModule(mod, exposesMap);
}
});
return {
remotes,
exposesMap,
sharedMap
};
}
constructor(options, modules, { bundler }){
this._bundler = 'webpack';
this._remoteManager = new managers_namespaceObject.RemoteManager();
this._sharedManager = new managers_namespaceObject.SharedManager();
this._options = options;
this._modules = modules;
this._bundler = bundler;
this._containerManager = new managers_namespaceObject.ContainerManager();
this._containerManager.init(options);
this._remoteManager = new managers_namespaceObject.RemoteManager();
this._remoteManager.init(options);
this._sharedManager = new managers_namespaceObject.SharedManager();
this._sharedManager.init(options);
}
}
exports.ModuleHandler = __webpack_exports__.ModuleHandler;
exports.getExposeItem = __webpack_exports__.getExposeItem;
exports.getExposeName = __webpack_exports__.getExposeName;
exports.getShareItem = __webpack_exports__.getShareItem;
for(var __webpack_i__ in __webpack_exports__) {
if(["ModuleHandler","getExposeItem","getExposeName","getShareItem"].indexOf(__webpack_i__) === -1) {
exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
}
}
Object.defineProperty(exports, '__esModule', { value: true });

View File

@@ -0,0 +1,446 @@
import { composeKeyWithSeparator } from "@module-federation/sdk";
import path from "path";
import { ContainerManager, RemoteManager, SharedManager } from "@module-federation/managers";
import { getFileNameWithOutExt } from "./utils.mjs";
;// CONCATENATED MODULE: external "@module-federation/sdk"
;// CONCATENATED MODULE: external "path"
;// CONCATENATED MODULE: external "@module-federation/managers"
;// CONCATENATED MODULE: external "./utils.mjs"
;// CONCATENATED MODULE: ./src/ModuleHandler.ts
const isNonEmptyString = (value)=>{
return typeof value === 'string' && value.trim().length > 0;
};
const normalizeExposeValue = (exposeValue)=>{
if (!exposeValue) {
return undefined;
}
const toImportArray = (value)=>{
if (isNonEmptyString(value)) {
return [
value
];
}
if (Array.isArray(value)) {
const normalized = value.filter(isNonEmptyString);
return normalized.length ? normalized : undefined;
}
return undefined;
};
if (typeof exposeValue === 'object') {
if ('import' in exposeValue) {
const { import: rawImport, name } = exposeValue;
const normalizedImport = toImportArray(rawImport);
if (!(normalizedImport === null || normalizedImport === void 0 ? void 0 : normalizedImport.length)) {
return undefined;
}
return {
import: normalizedImport,
...isNonEmptyString(name) ? {
name
} : {}
};
}
return undefined;
}
const normalizedImport = toImportArray(exposeValue);
if (!(normalizedImport === null || normalizedImport === void 0 ? void 0 : normalizedImport.length)) {
return undefined;
}
return {
import: normalizedImport
};
};
const parseContainerExposeEntries = (identifier)=>{
const startIndex = identifier.indexOf('[');
if (startIndex < 0) {
return undefined;
}
let depth = 0;
let inString = false;
let isEscaped = false;
for(let cursor = startIndex; cursor < identifier.length; cursor++){
const char = identifier[cursor];
if (isEscaped) {
isEscaped = false;
continue;
}
if (char === '\\') {
isEscaped = true;
continue;
}
if (char === '"') {
inString = !inString;
continue;
}
if (inString) {
continue;
}
if (char === '[') {
depth++;
} else if (char === ']') {
depth--;
if (depth === 0) {
const serialized = identifier.slice(startIndex, cursor + 1);
try {
return JSON.parse(serialized);
} catch {
return undefined;
}
}
}
}
return undefined;
};
const getExposeName = (exposeKey)=>{
return exposeKey.replace('./', '');
};
function getExposeItem({ exposeKey, name, file }) {
const exposeModuleName = getExposeName(exposeKey);
return {
path: exposeKey,
id: composeKeyWithSeparator(name, exposeModuleName),
name: exposeModuleName,
// @ts-ignore to deduplicate
requires: [],
file: path.relative(process.cwd(), file.import[0]),
assets: {
js: {
async: [],
sync: []
},
css: {
async: [],
sync: []
}
}
};
}
const getShareItem = ({ pkgName, normalizedShareOptions, pkgVersion, hostName })=>{
return {
...normalizedShareOptions,
id: `${hostName}:${pkgName}`,
requiredVersion: (normalizedShareOptions === null || normalizedShareOptions === void 0 ? void 0 : normalizedShareOptions.requiredVersion) || `^${pkgVersion}`,
name: pkgName,
version: pkgVersion,
assets: {
js: {
async: [],
sync: []
},
css: {
async: [],
sync: []
}
},
// @ts-ignore to deduplicate
usedIn: new Set(),
usedExports: [],
fallback: ''
};
};
class ModuleHandler {
get isRspack() {
return this._bundler === 'rspack';
}
_handleSharedModule(mod, sharedMap, exposesMap) {
const { identifier, moduleType } = mod;
if (!identifier) {
return;
}
const sharedManagerNormalizedOptions = this._sharedManager.normalizedOptions;
const initShared = (pkgName, pkgVersion)=>{
if (sharedMap[pkgName]) {
return;
}
sharedMap[pkgName] = getShareItem({
pkgName,
pkgVersion,
normalizedShareOptions: sharedManagerNormalizedOptions[pkgName],
hostName: this._options.name
});
};
const collectRelationshipMap = (mod, pkgName)=>{
const { issuerName, reasons } = mod;
if (issuerName) {
if (exposesMap[getFileNameWithOutExt(issuerName)]) {
const expose = exposesMap[getFileNameWithOutExt(issuerName)];
// @ts-ignore use Set to deduplicate
expose.requires.push(pkgName);
// @ts-ignore use Set to deduplicate
sharedMap[pkgName].usedIn.add(expose.path);
}
}
if (reasons) {
reasons.forEach(({ resolvedModule, moduleName })=>{
let exposeModName = this.isRspack ? moduleName : resolvedModule;
// filters out entrypoints
if (exposeModName) {
if (exposesMap[getFileNameWithOutExt(exposeModName)]) {
const expose = exposesMap[getFileNameWithOutExt(exposeModName)];
// @ts-ignore to deduplicate
expose.requires.push(pkgName);
// @ts-ignore to deduplicate
sharedMap[pkgName].usedIn.add(expose.path);
}
}
});
}
};
const parseResolvedIdentifier = (nameAndVersion)=>{
let name = '';
let version = '';
if (nameAndVersion.startsWith('@')) {
const splitInfo = nameAndVersion.split('@');
splitInfo[0] = '@';
name = splitInfo[0] + splitInfo[1];
version = splitInfo[2];
} else if (nameAndVersion.includes('@')) {
[name, version] = nameAndVersion.split('@');
version = version.replace(/[\^~>|>=]/g, '');
}
return {
name,
version
};
};
if (moduleType === 'provide-module') {
// identifier(rspack) = provide shared module (default) react@18.2.0 = /temp/node_modules/.pnpm/react@18.2.0/node_modules/react/index.js
// identifier(webpack) = provide module (default) react@18.2.0 = /temp/node_modules/.pnpm/react@18.2.0/node_modules/react/index.js
const data = identifier.split(' ');
const nameAndVersion = this.isRspack ? data[4] : data[3];
const { name, version } = parseResolvedIdentifier(nameAndVersion);
if (name && version) {
initShared(name, version);
collectRelationshipMap(mod, name);
}
}
if (moduleType === 'consume-shared-module') {
// identifier(rspack) = consume shared module (default) lodash/get@^4.17.21 (strict) (fallback: /temp/node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/get.js)
// identifier(webpack) = consume-shared-module|default|react-dom|!=1.8...2...0|false|/temp/node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/index.js|true|false
const SEPARATOR = this.isRspack ? ' ' : '|';
const data = identifier.split(SEPARATOR);
let pkgName = '';
let pkgVersion = '';
if (this.isRspack) {
const nameAndVersion = data[4];
const res = parseResolvedIdentifier(nameAndVersion);
pkgName = res.name;
pkgVersion = res.version;
} else {
pkgName = data[2];
const pkgVersionRange = data[3];
pkgVersion = '';
if (pkgVersionRange.startsWith('=')) {
pkgVersion = data[3].replace('=', '');
} else {
if (sharedManagerNormalizedOptions[pkgName]) {
pkgVersion = sharedManagerNormalizedOptions[pkgName].version;
} else {
const fullPkgName = pkgName.split('/').slice(0, -1).join('/');
// pkgName: react-dom/
if (sharedManagerNormalizedOptions[`${fullPkgName}/`]) {
if (sharedManagerNormalizedOptions[fullPkgName]) {
pkgVersion = sharedManagerNormalizedOptions[fullPkgName].version;
} else {
pkgVersion = sharedManagerNormalizedOptions[`${fullPkgName}/`].version;
}
}
}
}
}
if (pkgName && pkgVersion) {
initShared(pkgName, pkgVersion);
collectRelationshipMap(mod, pkgName);
}
}
}
_handleRemoteModule(mod, remotes, remotesConsumerMap) {
const { identifier, reasons, nameForCondition } = mod;
if (!identifier) {
return;
}
const remoteManagerNormalizedOptions = this._remoteManager.normalizedOptions;
// identifier = remote (default) webpack/container/reference/app2 ./Button
const data = identifier.split(' ');
if (data.length === 4) {
const moduleName = data[3].replace('./', '');
const remoteAlias = data[2].replace('webpack/container/reference/', '');
const normalizedRemote = remoteManagerNormalizedOptions[remoteAlias];
const basicRemote = {
alias: normalizedRemote.alias,
consumingFederationContainerName: this._options.name || '',
federationContainerName: remoteManagerNormalizedOptions[remoteAlias].name,
moduleName,
// @ts-ignore to deduplicate
usedIn: new Set()
};
if (!nameForCondition) {
return;
}
let remote;
if ('version' in normalizedRemote) {
remote = {
...basicRemote,
version: normalizedRemote.version
};
} else {
remote = {
...basicRemote,
entry: normalizedRemote.entry
};
}
remotes.push(remote);
remotesConsumerMap[nameForCondition] = remote;
}
if (reasons) {
reasons.forEach(({ userRequest, resolvedModule, moduleName })=>{
let exposeModName = this.isRspack ? moduleName : resolvedModule;
if (userRequest && exposeModName && remotesConsumerMap[userRequest]) {
// @ts-ignore to deduplicate
remotesConsumerMap[userRequest].usedIn.add(exposeModName.replace('./', ''));
}
});
}
}
_handleContainerModule(mod, exposesMap) {
const { identifier } = mod;
if (!identifier) {
return;
}
// identifier: container entry (default) [[".",{"import":["./src/routes/page.tsx"],"name":"__federation_expose_default_export"}]]'
const entries = parseContainerExposeEntries(identifier) ?? this._getContainerExposeEntriesFromOptions();
if (!entries) {
return;
}
entries.forEach(([prefixedName, file])=>{
// TODO: support multiple import
exposesMap[getFileNameWithOutExt(file.import[0])] = getExposeItem({
exposeKey: prefixedName,
name: this._options.name,
file
});
});
}
_getContainerExposeEntriesFromOptions() {
const exposes = this._containerManager.containerPluginExposesOptions;
const normalizedEntries = Object.entries(exposes).reduce((acc, [exposeKey, exposeOptions])=>{
const normalizedExpose = normalizeExposeValue(exposeOptions);
if (!(normalizedExpose === null || normalizedExpose === void 0 ? void 0 : normalizedExpose.import.length)) {
return acc;
}
acc.push([
exposeKey,
normalizedExpose
]);
return acc;
}, []);
if (normalizedEntries.length) {
return normalizedEntries;
}
const rawExposes = this._options.exposes;
if (!rawExposes || Array.isArray(rawExposes)) {
return undefined;
}
const normalizedFromOptions = Object.entries(rawExposes).reduce((acc, [exposeKey, exposeOptions])=>{
const normalizedExpose = normalizeExposeValue(exposeOptions);
if (!(normalizedExpose === null || normalizedExpose === void 0 ? void 0 : normalizedExpose.import.length)) {
return acc;
}
acc.push([
exposeKey,
normalizedExpose
]);
return acc;
}, []);
return normalizedFromOptions.length ? normalizedFromOptions : undefined;
}
_initializeExposesFromOptions(exposesMap) {
if (!this._options.name || !this._containerManager.enable) {
return;
}
const exposes = this._containerManager.containerPluginExposesOptions;
Object.entries(exposes).forEach(([exposeKey, exposeOptions])=>{
var _exposeOptions_import;
if (!((_exposeOptions_import = exposeOptions.import) === null || _exposeOptions_import === void 0 ? void 0 : _exposeOptions_import.length)) {
return;
}
const [exposeImport] = exposeOptions.import;
if (!exposeImport) {
return;
}
const exposeMapKey = getFileNameWithOutExt(exposeImport);
if (!exposesMap[exposeMapKey]) {
exposesMap[exposeMapKey] = getExposeItem({
exposeKey,
name: this._options.name,
file: exposeOptions
});
}
});
}
collect() {
const remotes = [];
const remotesConsumerMap = {};
const exposesMap = {};
const sharedMap = {};
this._initializeExposesFromOptions(exposesMap);
const isSharedModule = (moduleType)=>{
return Boolean(moduleType && [
'provide-module',
'consume-shared-module'
].includes(moduleType));
};
const isContainerModule = (identifier)=>{
return identifier.startsWith('container entry');
};
const isRemoteModule = (identifier)=>{
return identifier.startsWith('remote ');
};
// handle remote/expose
this._modules.forEach((mod)=>{
const { identifier, reasons, nameForCondition, moduleType } = mod;
if (!identifier) {
return;
}
if (isSharedModule(moduleType)) {
this._handleSharedModule(mod, sharedMap, exposesMap);
}
if (isRemoteModule(identifier)) {
this._handleRemoteModule(mod, remotes, remotesConsumerMap);
} else if (isContainerModule(identifier)) {
this._handleContainerModule(mod, exposesMap);
}
});
return {
remotes,
exposesMap,
sharedMap
};
}
constructor(options, modules, { bundler }){
this._bundler = 'webpack';
this._remoteManager = new RemoteManager();
this._sharedManager = new SharedManager();
this._options = options;
this._modules = modules;
this._bundler = bundler;
this._containerManager = new ContainerManager();
this._containerManager.init(options);
this._remoteManager = new RemoteManager();
this._remoteManager.init(options);
this._sharedManager = new SharedManager();
this._sharedManager.init(options);
}
}
export { ModuleHandler, getExposeItem, getExposeName, getShareItem };

View File

@@ -0,0 +1,29 @@
import { BasicStatsMetaData, StatsMetaData, Stats, moduleFederationPlugin } from '@module-federation/sdk';
import { Compilation, Compiler } from 'webpack';
declare class StatsManager {
private _options;
private _publicPath?;
private _pluginVersion?;
private _bundler;
private _containerManager;
private _remoteManager;
private _sharedManager;
private _pkgJsonManager;
private getBuildInfo;
get fileName(): string;
setMetaDataPublicPath(metaData: BasicStatsMetaData, compiler: Compiler): StatsMetaData;
private _getMetaData;
private _getFilteredModules;
private _getModuleAssets;
private _getProvideSharedAssets;
private _generateStats;
getPublicPath(compiler: Compiler): string;
init(options: moduleFederationPlugin.ModuleFederationPluginOptions, { pluginVersion, bundler, }: {
pluginVersion: string;
bundler: 'webpack' | 'rspack';
}): void;
updateStats(stats: Stats, compiler: Compiler): Stats;
generateStats(compiler: Compiler, compilation: Compilation): Promise<Stats>;
validate(compiler: Compiler): boolean;
}
export { StatsManager };

View File

@@ -0,0 +1,535 @@
"use strict";
const __rslib_import_meta_url__ = /*#__PURE__*/ (function () {
return typeof document === 'undefined'
? new (require('url'.replace('', '')).URL)('file:' + __filename).href
: (document.currentScript && document.currentScript.src) ||
new URL('main.js', document.baseURI).href;
})();
;
// The require scope
var __webpack_require__ = {};
/************************************************************************/
// webpack/runtime/compat_get_default_export
(() => {
// getDefaultExport function for compatibility with non-ESM modules
__webpack_require__.n = (module) => {
var getter = module && module.__esModule ?
() => (module['default']) :
() => (module);
__webpack_require__.d(getter, { a: getter });
return getter;
};
})();
// webpack/runtime/define_property_getters
(() => {
__webpack_require__.d = (exports, definition) => {
for(var key in definition) {
if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
}
}
};
})();
// webpack/runtime/has_own_property
(() => {
__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
})();
// webpack/runtime/make_namespace_object
(() => {
// define __esModule on exports
__webpack_require__.r = (exports) => {
if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
}
Object.defineProperty(exports, '__esModule', { value: true });
};
})();
/************************************************************************/
var __webpack_exports__ = {};
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
StatsManager: () => (/* binding */ StatsManager)
});
;// CONCATENATED MODULE: external "@module-federation/sdk"
const sdk_namespaceObject = require("@module-federation/sdk");
;// CONCATENATED MODULE: external "./utils.js"
const external_utils_js_namespaceObject = require("./utils.js");
;// CONCATENATED MODULE: external "./logger.js"
const external_logger_js_namespaceObject = require("./logger.js");
var external_logger_js_default = /*#__PURE__*/__webpack_require__.n(external_logger_js_namespaceObject);
;// CONCATENATED MODULE: external "@module-federation/managers"
const managers_namespaceObject = require("@module-federation/managers");
;// CONCATENATED MODULE: external "./constants.js"
const external_constants_js_namespaceObject = require("./constants.js");
;// CONCATENATED MODULE: external "./ModuleHandler.js"
const external_ModuleHandler_js_namespaceObject = require("./ModuleHandler.js");
;// CONCATENATED MODULE: ./src/StatsManager.ts
/* eslint-disable max-lines-per-function */ /* eslint-disable @typescript-eslint/member-ordering */ /* eslint-disable max-depth */
class StatsManager {
getBuildInfo(context, target) {
const rootPath = context || process.cwd();
const pkg = this._pkgJsonManager.readPKGJson(rootPath);
const statsBuildInfo = {
buildVersion: managers_namespaceObject.utils.getBuildVersion(rootPath),
buildName: managers_namespaceObject.utils.getBuildName() || pkg['name']
};
if (this._sharedManager.enableTreeShaking) {
statsBuildInfo.target = target ? Array.isArray(target) ? target : [
target
] : [];
statsBuildInfo.plugins = this._options.treeShakingSharedPlugins || [];
statsBuildInfo.excludePlugins = this._options.treeShakingSharedExcludePlugins || [];
}
return statsBuildInfo;
}
get fileName() {
return (0,sdk_namespaceObject.getManifestFileName)(this._options.manifest).statsFileName;
}
setMetaDataPublicPath(metaData, compiler) {
if (this._options.getPublicPath) {
if ('publicPath' in metaData) {
// @ts-ignore
delete metaData.publicPath;
}
metaData.getPublicPath = this._options.getPublicPath;
} else {
metaData.publicPath = this.getPublicPath(compiler);
}
return metaData;
}
_getMetaData(compiler, compilation, extraOptions) {
var _this__options_library, _this__options;
const { context } = compiler.options;
const { _options: { name } } = this;
const buildInfo = this.getBuildInfo(context, compilation.options.target || '');
const type = this._pkgJsonManager.getExposeGarfishModuleType(context || process.cwd());
const getRemoteEntryName = ()=>{
if (!this._containerManager.enable) {
return '';
}
(0,external_utils_js_namespaceObject.assert)(name, 'name is required');
const remoteEntryPoint = compilation.entrypoints.get(name);
(0,external_utils_js_namespaceObject.assert)(remoteEntryPoint, 'Can not get remoteEntry entryPoint!');
const remoteEntryNameChunk = compilation.namedChunks.get(name);
(0,external_utils_js_namespaceObject.assert)(remoteEntryNameChunk, 'Can not get remoteEntry chunk!');
const files = Array.from(remoteEntryNameChunk.files).filter((f)=>!f.includes(external_constants_js_namespaceObject.HOT_UPDATE_SUFFIX) && !f.endsWith('.css'));
(0,external_utils_js_namespaceObject.assert)(files.length > 0, 'no files found for remoteEntry chunk');
(0,external_utils_js_namespaceObject.assert)(files.length === 1, `remoteEntry chunk should not have multiple files!, current files: ${files.join(',')}`);
const remoteEntryName = files[0];
return remoteEntryName;
};
const globalName = this._containerManager.globalEntryName;
(0,external_utils_js_namespaceObject.assert)(globalName, 'Can not get library.name, please ensure you have set library.name and the type is "string" !');
(0,external_utils_js_namespaceObject.assert)(this._pluginVersion, 'Can not get pluginVersion, please ensure you have set pluginVersion !');
const metaData = {
name: name,
type,
buildInfo,
remoteEntry: {
name: getRemoteEntryName(),
path: '',
// same as the types supported by runtime, currently only global/var/script is supported
type: ((_this__options = this._options) === null || _this__options === void 0 ? void 0 : (_this__options_library = _this__options.library) === null || _this__options_library === void 0 ? void 0 : _this__options_library.type) || 'global'
},
types: (0,external_utils_js_namespaceObject.getTypesMetaInfo)(this._options, compiler.context),
globalName: globalName,
pluginVersion: this._pluginVersion
};
return this.setMetaDataPublicPath(metaData, compiler);
}
_getFilteredModules(stats) {
const filteredModules = stats.modules.filter((module)=>{
if (!module || !module.name) {
return false;
}
const array = [
module.name.includes('container entry'),
module.name.includes('remote '),
module.name.includes('shared module '),
module.name.includes('provide module ')
];
return array.some((item)=>item);
});
return filteredModules;
}
_getModuleAssets(compilation, entryPointNames) {
const { chunks } = compilation;
const { exposeFileNameImportMap } = this._containerManager;
const assets = {};
chunks.forEach((chunk)=>{
if (typeof chunk.name !== 'string') return;
// Support split chunks caused by splitChunks.maxSize:
// A chunk named "__federation_expose_Foo" may be split into
// "__federation_expose_Foo-<hash>" chunks, so we match both exact
// and prefix+dash patterns.
const matchedKey = exposeFileNameImportMap[chunk.name] !== undefined ? chunk.name : Object.keys(exposeFileNameImportMap).find((key)=>chunk.name.startsWith(key + '-'));
if (!matchedKey) return;
// TODO: support multiple import
const exposeKey = exposeFileNameImportMap[matchedKey][0];
const assetKey = (0,external_utils_js_namespaceObject.getFileNameWithOutExt)(exposeKey);
const chunkAssets = (0,external_utils_js_namespaceObject.getAssetsByChunk)(chunk, entryPointNames);
if (!assets[assetKey]) {
assets[assetKey] = chunkAssets;
} else {
// Merge split chunk assets, deduplicating with Set
assets[assetKey] = {
js: {
sync: [
...new Set([
...assets[assetKey].js.sync,
...chunkAssets.js.sync
])
],
async: [
...new Set([
...assets[assetKey].js.async,
...chunkAssets.js.async
])
]
},
css: {
sync: [
...new Set([
...assets[assetKey].css.sync,
...chunkAssets.css.sync
])
],
async: [
...new Set([
...assets[assetKey].css.async,
...chunkAssets.css.async
])
]
}
};
}
});
return assets;
}
_getProvideSharedAssets(compilation, stats, entryPointNames) {
const sharedModules = stats.modules.filter((module)=>{
if (!module || !module.name) {
return false;
}
const array = [
module.name.includes('consume shared module ')
];
return array.some((item)=>item);
});
const manifestOverrideChunkIDMap = {};
const effectiveSharedModules = (0,external_utils_js_namespaceObject.getSharedModules)(stats, sharedModules);
effectiveSharedModules.forEach((item)=>{
const [sharedModuleName, sharedModule] = item;
if (!manifestOverrideChunkIDMap[sharedModuleName]) {
manifestOverrideChunkIDMap[sharedModuleName] = {
async: new Set(),
sync: new Set()
};
}
sharedModule.chunks.forEach((chunkID)=>{
const chunk = (0,external_utils_js_namespaceObject.findChunk)(chunkID, compilation.chunks);
manifestOverrideChunkIDMap[sharedModuleName].sync.add(chunkID);
if (!chunk) {
return;
}
[
...chunk.groupsIterable
].forEach((group)=>{
if (group.name && !entryPointNames.includes(group.name)) {
manifestOverrideChunkIDMap[sharedModuleName].sync.add(group.id);
}
});
});
});
const assets = {
js: {
async: [],
sync: []
},
css: {
async: [],
sync: []
}
};
Object.keys(manifestOverrideChunkIDMap).forEach((override)=>{
const asyncAssets = (0,external_utils_js_namespaceObject.getAssetsByChunkIDs)(compilation, {
[override]: manifestOverrideChunkIDMap[override].async
});
const syncAssets = (0,external_utils_js_namespaceObject.getAssetsByChunkIDs)(compilation, {
[override]: manifestOverrideChunkIDMap[override].sync
});
assets[override] = {
js: {
async: asyncAssets[override].js,
sync: syncAssets[override].js
},
css: {
async: asyncAssets[override].css,
sync: syncAssets[override].css
}
};
});
return assets;
}
async _generateStats(compiler, compilation, extraOptions) {
try {
const { name, manifest: manifestOptions = {}, exposes = {} } = this._options;
const metaData = this._getMetaData(compiler, compilation, extraOptions);
const stats = {
id: name,
name: name,
metaData,
shared: [],
remotes: [],
exposes: []
};
if (typeof manifestOptions === 'object' && manifestOptions.disableAssetsAnalyze) {
const remotes = this._remoteManager.statsRemoteWithEmptyUsedIn;
stats.remotes = remotes;
stats.exposes = Object.keys(exposes).map((exposeKey)=>{
return (0,external_ModuleHandler_js_namespaceObject.getExposeItem)({
exposeKey,
name: name,
file: {
import: exposes[exposeKey].import
}
});
});
stats.shared = Object.entries(this._sharedManager.normalizedOptions).reduce((sum, cur)=>{
const [pkgName, normalizedShareOptions] = cur;
sum.push((0,external_ModuleHandler_js_namespaceObject.getShareItem)({
pkgName,
normalizedShareOptions,
pkgVersion: normalizedShareOptions.version || managers_namespaceObject.UNKNOWN_MODULE_NAME,
hostName: name
}));
return sum;
}, []);
return stats;
}
const liveStats = compilation.getStats();
const statsOptions = {
all: false,
modules: true,
builtAt: true,
hash: true,
ids: true,
version: true,
entrypoints: true,
assets: false,
chunks: false,
reasons: true
};
if (this._bundler === 'webpack') {
statsOptions['cached'] = true;
}
statsOptions['cachedModules'] = true;
const webpackStats = liveStats.toJson(statsOptions);
const filteredModules = this._getFilteredModules(webpackStats);
const moduleHandler = new external_ModuleHandler_js_namespaceObject.ModuleHandler(this._options, filteredModules, {
bundler: this._bundler
});
const { remotes, exposesMap, sharedMap } = moduleHandler.collect();
const entryPointNames = [
...compilation.entrypoints.values()
].map((e)=>e.name).filter((v)=>!!v);
await Promise.all([
new Promise((resolve)=>{
const sharedAssets = this._getProvideSharedAssets(compilation, webpackStats, entryPointNames);
Object.keys(sharedMap).forEach((sharedKey)=>{
const assets = sharedAssets[sharedKey];
if (assets) {
sharedMap[sharedKey].assets = assets;
}
});
resolve();
}),
new Promise((resolve)=>{
const moduleAssets = this._getModuleAssets(compilation, entryPointNames);
Object.keys(exposesMap).forEach((exposeKey)=>{
const assets = moduleAssets[exposeKey];
if (assets) {
exposesMap[exposeKey].assets = assets;
}
exposesMap[exposeKey].requires = Array.from(new Set(exposesMap[exposeKey].requires));
});
resolve();
})
]);
await Promise.all([
new Promise((resolve)=>{
const remoteMemo = new Set();
stats.remotes = remotes.map((remote)=>{
remoteMemo.add(remote.federationContainerName);
return {
...remote,
usedIn: Array.from(remote.usedIn.values())
};
});
const statsRemoteWithEmptyUsedIn = this._remoteManager.statsRemoteWithEmptyUsedIn;
statsRemoteWithEmptyUsedIn.forEach((remoteInfo)=>{
if (!remoteMemo.has(remoteInfo.federationContainerName)) {
stats.remotes.push(remoteInfo);
}
});
resolve();
}),
new Promise((resolve)=>{
stats.shared = Object.values(sharedMap).map((shared)=>({
...shared,
usedIn: Array.from(shared.usedIn)
}));
resolve();
})
]);
await new Promise((resolve)=>{
const sharedAssets = stats.shared.reduce((sum, shared)=>{
const { js, css } = shared.assets;
[
...js.sync,
...js.async,
...css.async,
css.sync
].forEach((asset)=>{
sum.add(asset);
});
return sum;
}, new Set());
const { fileExposeKeyMap } = this._containerManager;
stats.exposes = [];
Object.entries(fileExposeKeyMap).forEach(([exposeFileWithoutExt, exposeKeySet])=>{
const expose = exposesMap[exposeFileWithoutExt] || {
assets: {
js: {
sync: [],
async: []
},
css: {
sync: [],
async: []
}
}
};
exposeKeySet.forEach((exposeKey)=>{
const { js, css } = expose.assets;
const exposeModuleName = (0,external_ModuleHandler_js_namespaceObject.getExposeName)(exposeKey);
stats.exposes.push({
...expose,
path: exposeKey,
id: (0,sdk_namespaceObject.composeKeyWithSeparator)(this._options.name, exposeModuleName),
name: exposeModuleName,
assets: {
js: {
sync: js.sync.filter((asset)=>!sharedAssets.has(asset)),
async: js.async.filter((asset)=>!sharedAssets.has(asset))
},
css: {
sync: css.sync.filter((asset)=>!sharedAssets.has(asset)),
async: css.async.filter((asset)=>!sharedAssets.has(asset))
}
}
});
});
});
Object.values(exposesMap).map((expose)=>{
const { js, css } = expose.assets;
return {
...expose,
assets: {
js: {
sync: js.sync.filter((asset)=>!sharedAssets.has(asset)),
async: js.async.filter((asset)=>!sharedAssets.has(asset))
},
css: {
sync: css.sync.filter((asset)=>!sharedAssets.has(asset)),
async: css.async.filter((asset)=>!sharedAssets.has(asset))
}
}
};
});
resolve();
});
return stats;
} catch (err) {
throw err;
}
}
getPublicPath(compiler) {
if (this._publicPath) {
return this._publicPath;
}
const { output: { publicPath: originalPublicPath } } = compiler.options;
let publicPath = originalPublicPath;
this._publicPath = publicPath;
return publicPath;
}
init(options, { pluginVersion, bundler }) {
this._options = options;
this._pluginVersion = pluginVersion;
this._bundler = bundler;
this._containerManager = new managers_namespaceObject.ContainerManager();
this._containerManager.init(options);
this._remoteManager = new managers_namespaceObject.RemoteManager();
this._remoteManager.init(options);
this._sharedManager = new managers_namespaceObject.SharedManager();
this._sharedManager.init(options);
}
updateStats(stats, compiler) {
const { metaData } = stats;
if (!metaData.types) {
metaData.types = (0,external_utils_js_namespaceObject.getTypesMetaInfo)(this._options, compiler.context);
}
if (!metaData.pluginVersion) {
metaData.pluginVersion = this._pluginVersion;
}
this.setMetaDataPublicPath(metaData, compiler);
return stats;
}
async generateStats(compiler, compilation) {
try {
const stats = await this._generateStats(compiler, compilation);
return stats;
} catch (err) {
throw err;
}
}
validate(compiler) {
const { output: { publicPath } } = compiler.options;
if (typeof publicPath !== 'string') {
external_logger_js_default().warn(`Manifest will not generate, because publicPath can only be string, but got '${publicPath}'`);
return false;
} else if (publicPath === 'auto') {
external_logger_js_default().warn(`Manifest will use absolute path resolution via its host at runtime, reason: publicPath='${publicPath}'`);
return true;
}
return true;
}
constructor(){
this._options = {};
this._bundler = 'webpack';
this._containerManager = new managers_namespaceObject.ContainerManager();
this._remoteManager = new managers_namespaceObject.RemoteManager();
this._sharedManager = new managers_namespaceObject.SharedManager();
this._pkgJsonManager = new managers_namespaceObject.PKGJsonManager();
}
}
exports.StatsManager = __webpack_exports__.StatsManager;
for(var __webpack_i__ in __webpack_exports__) {
if(["StatsManager"].indexOf(__webpack_i__) === -1) {
exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
}
}
Object.defineProperty(exports, '__esModule', { value: true });

View File

@@ -0,0 +1,477 @@
import { composeKeyWithSeparator, getManifestFileName } from "@module-federation/sdk";
import { assert, findChunk, getAssetsByChunk, getAssetsByChunkIDs, getFileNameWithOutExt, getSharedModules, getTypesMetaInfo } from "./utils.mjs";
import logger from "./logger.mjs";
import { ContainerManager, PKGJsonManager, RemoteManager, SharedManager, UNKNOWN_MODULE_NAME, utils } from "@module-federation/managers";
import { HOT_UPDATE_SUFFIX } from "./constants.mjs";
import { ModuleHandler, getExposeItem, getExposeName, getShareItem } from "./ModuleHandler.mjs";
;// CONCATENATED MODULE: external "@module-federation/sdk"
;// CONCATENATED MODULE: external "./utils.mjs"
;// CONCATENATED MODULE: external "./logger.mjs"
;// CONCATENATED MODULE: external "@module-federation/managers"
;// CONCATENATED MODULE: external "./constants.mjs"
;// CONCATENATED MODULE: external "./ModuleHandler.mjs"
;// CONCATENATED MODULE: ./src/StatsManager.ts
/* eslint-disable max-lines-per-function */ /* eslint-disable @typescript-eslint/member-ordering */ /* eslint-disable max-depth */
class StatsManager {
getBuildInfo(context, target) {
const rootPath = context || process.cwd();
const pkg = this._pkgJsonManager.readPKGJson(rootPath);
const statsBuildInfo = {
buildVersion: utils.getBuildVersion(rootPath),
buildName: utils.getBuildName() || pkg['name']
};
if (this._sharedManager.enableTreeShaking) {
statsBuildInfo.target = target ? Array.isArray(target) ? target : [
target
] : [];
statsBuildInfo.plugins = this._options.treeShakingSharedPlugins || [];
statsBuildInfo.excludePlugins = this._options.treeShakingSharedExcludePlugins || [];
}
return statsBuildInfo;
}
get fileName() {
return getManifestFileName(this._options.manifest).statsFileName;
}
setMetaDataPublicPath(metaData, compiler) {
if (this._options.getPublicPath) {
if ('publicPath' in metaData) {
// @ts-ignore
delete metaData.publicPath;
}
metaData.getPublicPath = this._options.getPublicPath;
} else {
metaData.publicPath = this.getPublicPath(compiler);
}
return metaData;
}
_getMetaData(compiler, compilation, extraOptions) {
var _this__options_library, _this__options;
const { context } = compiler.options;
const { _options: { name } } = this;
const buildInfo = this.getBuildInfo(context, compilation.options.target || '');
const type = this._pkgJsonManager.getExposeGarfishModuleType(context || process.cwd());
const getRemoteEntryName = ()=>{
if (!this._containerManager.enable) {
return '';
}
assert(name, 'name is required');
const remoteEntryPoint = compilation.entrypoints.get(name);
assert(remoteEntryPoint, 'Can not get remoteEntry entryPoint!');
const remoteEntryNameChunk = compilation.namedChunks.get(name);
assert(remoteEntryNameChunk, 'Can not get remoteEntry chunk!');
const files = Array.from(remoteEntryNameChunk.files).filter((f)=>!f.includes(HOT_UPDATE_SUFFIX) && !f.endsWith('.css'));
assert(files.length > 0, 'no files found for remoteEntry chunk');
assert(files.length === 1, `remoteEntry chunk should not have multiple files!, current files: ${files.join(',')}`);
const remoteEntryName = files[0];
return remoteEntryName;
};
const globalName = this._containerManager.globalEntryName;
assert(globalName, 'Can not get library.name, please ensure you have set library.name and the type is "string" !');
assert(this._pluginVersion, 'Can not get pluginVersion, please ensure you have set pluginVersion !');
const metaData = {
name: name,
type,
buildInfo,
remoteEntry: {
name: getRemoteEntryName(),
path: '',
// same as the types supported by runtime, currently only global/var/script is supported
type: ((_this__options = this._options) === null || _this__options === void 0 ? void 0 : (_this__options_library = _this__options.library) === null || _this__options_library === void 0 ? void 0 : _this__options_library.type) || 'global'
},
types: getTypesMetaInfo(this._options, compiler.context),
globalName: globalName,
pluginVersion: this._pluginVersion
};
return this.setMetaDataPublicPath(metaData, compiler);
}
_getFilteredModules(stats) {
const filteredModules = stats.modules.filter((module)=>{
if (!module || !module.name) {
return false;
}
const array = [
module.name.includes('container entry'),
module.name.includes('remote '),
module.name.includes('shared module '),
module.name.includes('provide module ')
];
return array.some((item)=>item);
});
return filteredModules;
}
_getModuleAssets(compilation, entryPointNames) {
const { chunks } = compilation;
const { exposeFileNameImportMap } = this._containerManager;
const assets = {};
chunks.forEach((chunk)=>{
if (typeof chunk.name !== 'string') return;
// Support split chunks caused by splitChunks.maxSize:
// A chunk named "__federation_expose_Foo" may be split into
// "__federation_expose_Foo-<hash>" chunks, so we match both exact
// and prefix+dash patterns.
const matchedKey = exposeFileNameImportMap[chunk.name] !== undefined ? chunk.name : Object.keys(exposeFileNameImportMap).find((key)=>chunk.name.startsWith(key + '-'));
if (!matchedKey) return;
// TODO: support multiple import
const exposeKey = exposeFileNameImportMap[matchedKey][0];
const assetKey = getFileNameWithOutExt(exposeKey);
const chunkAssets = getAssetsByChunk(chunk, entryPointNames);
if (!assets[assetKey]) {
assets[assetKey] = chunkAssets;
} else {
// Merge split chunk assets, deduplicating with Set
assets[assetKey] = {
js: {
sync: [
...new Set([
...assets[assetKey].js.sync,
...chunkAssets.js.sync
])
],
async: [
...new Set([
...assets[assetKey].js.async,
...chunkAssets.js.async
])
]
},
css: {
sync: [
...new Set([
...assets[assetKey].css.sync,
...chunkAssets.css.sync
])
],
async: [
...new Set([
...assets[assetKey].css.async,
...chunkAssets.css.async
])
]
}
};
}
});
return assets;
}
_getProvideSharedAssets(compilation, stats, entryPointNames) {
const sharedModules = stats.modules.filter((module)=>{
if (!module || !module.name) {
return false;
}
const array = [
module.name.includes('consume shared module ')
];
return array.some((item)=>item);
});
const manifestOverrideChunkIDMap = {};
const effectiveSharedModules = getSharedModules(stats, sharedModules);
effectiveSharedModules.forEach((item)=>{
const [sharedModuleName, sharedModule] = item;
if (!manifestOverrideChunkIDMap[sharedModuleName]) {
manifestOverrideChunkIDMap[sharedModuleName] = {
async: new Set(),
sync: new Set()
};
}
sharedModule.chunks.forEach((chunkID)=>{
const chunk = findChunk(chunkID, compilation.chunks);
manifestOverrideChunkIDMap[sharedModuleName].sync.add(chunkID);
if (!chunk) {
return;
}
[
...chunk.groupsIterable
].forEach((group)=>{
if (group.name && !entryPointNames.includes(group.name)) {
manifestOverrideChunkIDMap[sharedModuleName].sync.add(group.id);
}
});
});
});
const assets = {
js: {
async: [],
sync: []
},
css: {
async: [],
sync: []
}
};
Object.keys(manifestOverrideChunkIDMap).forEach((override)=>{
const asyncAssets = getAssetsByChunkIDs(compilation, {
[override]: manifestOverrideChunkIDMap[override].async
});
const syncAssets = getAssetsByChunkIDs(compilation, {
[override]: manifestOverrideChunkIDMap[override].sync
});
assets[override] = {
js: {
async: asyncAssets[override].js,
sync: syncAssets[override].js
},
css: {
async: asyncAssets[override].css,
sync: syncAssets[override].css
}
};
});
return assets;
}
async _generateStats(compiler, compilation, extraOptions) {
try {
const { name, manifest: manifestOptions = {}, exposes = {} } = this._options;
const metaData = this._getMetaData(compiler, compilation, extraOptions);
const stats = {
id: name,
name: name,
metaData,
shared: [],
remotes: [],
exposes: []
};
if (typeof manifestOptions === 'object' && manifestOptions.disableAssetsAnalyze) {
const remotes = this._remoteManager.statsRemoteWithEmptyUsedIn;
stats.remotes = remotes;
stats.exposes = Object.keys(exposes).map((exposeKey)=>{
return getExposeItem({
exposeKey,
name: name,
file: {
import: exposes[exposeKey].import
}
});
});
stats.shared = Object.entries(this._sharedManager.normalizedOptions).reduce((sum, cur)=>{
const [pkgName, normalizedShareOptions] = cur;
sum.push(getShareItem({
pkgName,
normalizedShareOptions,
pkgVersion: normalizedShareOptions.version || UNKNOWN_MODULE_NAME,
hostName: name
}));
return sum;
}, []);
return stats;
}
const liveStats = compilation.getStats();
const statsOptions = {
all: false,
modules: true,
builtAt: true,
hash: true,
ids: true,
version: true,
entrypoints: true,
assets: false,
chunks: false,
reasons: true
};
if (this._bundler === 'webpack') {
statsOptions['cached'] = true;
}
statsOptions['cachedModules'] = true;
const webpackStats = liveStats.toJson(statsOptions);
const filteredModules = this._getFilteredModules(webpackStats);
const moduleHandler = new ModuleHandler(this._options, filteredModules, {
bundler: this._bundler
});
const { remotes, exposesMap, sharedMap } = moduleHandler.collect();
const entryPointNames = [
...compilation.entrypoints.values()
].map((e)=>e.name).filter((v)=>!!v);
await Promise.all([
new Promise((resolve)=>{
const sharedAssets = this._getProvideSharedAssets(compilation, webpackStats, entryPointNames);
Object.keys(sharedMap).forEach((sharedKey)=>{
const assets = sharedAssets[sharedKey];
if (assets) {
sharedMap[sharedKey].assets = assets;
}
});
resolve();
}),
new Promise((resolve)=>{
const moduleAssets = this._getModuleAssets(compilation, entryPointNames);
Object.keys(exposesMap).forEach((exposeKey)=>{
const assets = moduleAssets[exposeKey];
if (assets) {
exposesMap[exposeKey].assets = assets;
}
exposesMap[exposeKey].requires = Array.from(new Set(exposesMap[exposeKey].requires));
});
resolve();
})
]);
await Promise.all([
new Promise((resolve)=>{
const remoteMemo = new Set();
stats.remotes = remotes.map((remote)=>{
remoteMemo.add(remote.federationContainerName);
return {
...remote,
usedIn: Array.from(remote.usedIn.values())
};
});
const statsRemoteWithEmptyUsedIn = this._remoteManager.statsRemoteWithEmptyUsedIn;
statsRemoteWithEmptyUsedIn.forEach((remoteInfo)=>{
if (!remoteMemo.has(remoteInfo.federationContainerName)) {
stats.remotes.push(remoteInfo);
}
});
resolve();
}),
new Promise((resolve)=>{
stats.shared = Object.values(sharedMap).map((shared)=>({
...shared,
usedIn: Array.from(shared.usedIn)
}));
resolve();
})
]);
await new Promise((resolve)=>{
const sharedAssets = stats.shared.reduce((sum, shared)=>{
const { js, css } = shared.assets;
[
...js.sync,
...js.async,
...css.async,
css.sync
].forEach((asset)=>{
sum.add(asset);
});
return sum;
}, new Set());
const { fileExposeKeyMap } = this._containerManager;
stats.exposes = [];
Object.entries(fileExposeKeyMap).forEach(([exposeFileWithoutExt, exposeKeySet])=>{
const expose = exposesMap[exposeFileWithoutExt] || {
assets: {
js: {
sync: [],
async: []
},
css: {
sync: [],
async: []
}
}
};
exposeKeySet.forEach((exposeKey)=>{
const { js, css } = expose.assets;
const exposeModuleName = getExposeName(exposeKey);
stats.exposes.push({
...expose,
path: exposeKey,
id: composeKeyWithSeparator(this._options.name, exposeModuleName),
name: exposeModuleName,
assets: {
js: {
sync: js.sync.filter((asset)=>!sharedAssets.has(asset)),
async: js.async.filter((asset)=>!sharedAssets.has(asset))
},
css: {
sync: css.sync.filter((asset)=>!sharedAssets.has(asset)),
async: css.async.filter((asset)=>!sharedAssets.has(asset))
}
}
});
});
});
Object.values(exposesMap).map((expose)=>{
const { js, css } = expose.assets;
return {
...expose,
assets: {
js: {
sync: js.sync.filter((asset)=>!sharedAssets.has(asset)),
async: js.async.filter((asset)=>!sharedAssets.has(asset))
},
css: {
sync: css.sync.filter((asset)=>!sharedAssets.has(asset)),
async: css.async.filter((asset)=>!sharedAssets.has(asset))
}
}
};
});
resolve();
});
return stats;
} catch (err) {
throw err;
}
}
getPublicPath(compiler) {
if (this._publicPath) {
return this._publicPath;
}
const { output: { publicPath: originalPublicPath } } = compiler.options;
let publicPath = originalPublicPath;
this._publicPath = publicPath;
return publicPath;
}
init(options, { pluginVersion, bundler }) {
this._options = options;
this._pluginVersion = pluginVersion;
this._bundler = bundler;
this._containerManager = new ContainerManager();
this._containerManager.init(options);
this._remoteManager = new RemoteManager();
this._remoteManager.init(options);
this._sharedManager = new SharedManager();
this._sharedManager.init(options);
}
updateStats(stats, compiler) {
const { metaData } = stats;
if (!metaData.types) {
metaData.types = getTypesMetaInfo(this._options, compiler.context);
}
if (!metaData.pluginVersion) {
metaData.pluginVersion = this._pluginVersion;
}
this.setMetaDataPublicPath(metaData, compiler);
return stats;
}
async generateStats(compiler, compilation) {
try {
const stats = await this._generateStats(compiler, compilation);
return stats;
} catch (err) {
throw err;
}
}
validate(compiler) {
const { output: { publicPath } } = compiler.options;
if (typeof publicPath !== 'string') {
logger.warn(`Manifest will not generate, because publicPath can only be string, but got '${publicPath}'`);
return false;
} else if (publicPath === 'auto') {
logger.warn(`Manifest will use absolute path resolution via its host at runtime, reason: publicPath='${publicPath}'`);
return true;
}
return true;
}
constructor(){
this._options = {};
this._bundler = 'webpack';
this._containerManager = new ContainerManager();
this._remoteManager = new RemoteManager();
this._sharedManager = new SharedManager();
this._pkgJsonManager = new PKGJsonManager();
}
}
export { StatsManager };

View File

@@ -0,0 +1,15 @@
import { Compiler, WebpackPluginInstance } from 'webpack';
import { moduleFederationPlugin } from '@module-federation/sdk';
export declare class StatsPlugin implements WebpackPluginInstance {
readonly name = "StatsPlugin";
private _options;
private _statsManager;
private _manifestManager;
private _enable;
private _bundler;
constructor(options: moduleFederationPlugin.ModuleFederationPluginOptions, { pluginVersion, bundler, }: {
pluginVersion: string;
bundler: 'webpack' | 'rspack';
});
apply(compiler: Compiler): void;
}

View File

@@ -0,0 +1,171 @@
"use strict";
const __rslib_import_meta_url__ = /*#__PURE__*/ (function () {
return typeof document === 'undefined'
? new (require('url'.replace('', '')).URL)('file:' + __filename).href
: (document.currentScript && document.currentScript.src) ||
new URL('main.js', document.baseURI).href;
})();
;
// The require scope
var __webpack_require__ = {};
/************************************************************************/
// webpack/runtime/compat_get_default_export
(() => {
// getDefaultExport function for compatibility with non-ESM modules
__webpack_require__.n = (module) => {
var getter = module && module.__esModule ?
() => (module['default']) :
() => (module);
__webpack_require__.d(getter, { a: getter });
return getter;
};
})();
// webpack/runtime/define_property_getters
(() => {
__webpack_require__.d = (exports, definition) => {
for(var key in definition) {
if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
}
}
};
})();
// webpack/runtime/has_own_property
(() => {
__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
})();
// webpack/runtime/make_namespace_object
(() => {
// define __esModule on exports
__webpack_require__.r = (exports) => {
if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
}
Object.defineProperty(exports, '__esModule', { value: true });
};
})();
/************************************************************************/
var __webpack_exports__ = {};
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
StatsPlugin: () => (/* binding */ StatsPlugin)
});
;// CONCATENATED MODULE: external "@module-federation/sdk"
const sdk_namespaceObject = require("@module-federation/sdk");
;// CONCATENATED MODULE: external "./ManifestManager.js"
const external_ManifestManager_js_namespaceObject = require("./ManifestManager.js");
;// CONCATENATED MODULE: external "./StatsManager.js"
const external_StatsManager_js_namespaceObject = require("./StatsManager.js");
;// CONCATENATED MODULE: external "./constants.js"
const external_constants_js_namespaceObject = require("./constants.js");
;// CONCATENATED MODULE: external "./logger.js"
const external_logger_js_namespaceObject = require("./logger.js");
var external_logger_js_default = /*#__PURE__*/__webpack_require__.n(external_logger_js_namespaceObject);
;// CONCATENATED MODULE: ./src/StatsPlugin.ts
class StatsPlugin {
apply(compiler) {
(0,sdk_namespaceObject.bindLoggerToCompiler)((external_logger_js_default()), compiler, external_constants_js_namespaceObject.PLUGIN_IDENTIFIER);
if (!this._enable) {
return;
}
const res = this._statsManager.validate(compiler);
if (!res) {
return;
}
compiler.hooks.thisCompilation.tap('generateStats', (compilation)=>{
compilation.hooks.processAssets.tapPromise({
name: 'generateStats',
// @ts-ignore use runtime variable in case peer dep not installed
stage: compilation.constructor.PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER
}, async ()=>{
if (this._options.manifest !== false) {
const existedStats = compilation.getAsset(this._statsManager.fileName);
// new rspack should hit
if (existedStats) {
let updatedStats = this._statsManager.updateStats(JSON.parse(existedStats.source.source().toString()), compiler);
if (typeof this._options.manifest === 'object' && this._options.manifest.additionalData) {
updatedStats = await this._options.manifest.additionalData({
stats: updatedStats,
compiler,
compilation,
bundler: this._bundler
}) || updatedStats;
}
compilation.updateAsset(this._statsManager.fileName, new compiler.webpack.sources.RawSource(JSON.stringify(updatedStats, null, 2)));
const updatedManifest = this._manifestManager.updateManifest({
compilation,
stats: updatedStats,
publicPath: this._statsManager.getPublicPath(compiler),
compiler,
bundler: this._bundler
});
const source = new compiler.webpack.sources.RawSource(JSON.stringify(updatedManifest, null, 2));
compilation.updateAsset(this._manifestManager.fileName, source);
return;
}
// webpack + legacy rspack
let stats = await this._statsManager.generateStats(compiler, compilation);
if (typeof this._options.manifest === 'object' && this._options.manifest.additionalData) {
stats = await this._options.manifest.additionalData({
stats,
compiler,
compilation,
bundler: this._bundler
}) || stats;
}
const manifest = await this._manifestManager.generateManifest({
compilation,
stats: stats,
publicPath: this._statsManager.getPublicPath(compiler),
compiler,
bundler: this._bundler
});
compilation.emitAsset(this._statsManager.fileName, new compiler.webpack.sources.RawSource(JSON.stringify(stats, null, 2)));
compilation.emitAsset(this._manifestManager.fileName, new compiler.webpack.sources.RawSource(JSON.stringify(manifest, null, 2)));
}
});
});
}
constructor(options, { pluginVersion, bundler }){
this.name = 'StatsPlugin';
this._options = {};
this._statsManager = new external_StatsManager_js_namespaceObject.StatsManager();
this._manifestManager = new external_ManifestManager_js_namespaceObject.ManifestManager();
this._enable = true;
this._bundler = 'webpack';
try {
this._options = options;
this._bundler = bundler;
this._statsManager.init(this._options, {
pluginVersion,
bundler
});
this._manifestManager.init(this._options);
} catch (err) {
if (err instanceof Error) {
err.message = `[ ${external_constants_js_namespaceObject.PLUGIN_IDENTIFIER} ]: Manifest will not generate, because: ${err.message}`;
}
external_logger_js_default().error(err);
this._enable = false;
}
}
}
exports.StatsPlugin = __webpack_exports__.StatsPlugin;
for(var __webpack_i__ in __webpack_exports__) {
if(["StatsPlugin"].indexOf(__webpack_i__) === -1) {
exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
}
}
Object.defineProperty(exports, '__esModule', { value: true });

View File

@@ -0,0 +1,112 @@
import { bindLoggerToCompiler } from "@module-federation/sdk";
import { ManifestManager } from "./ManifestManager.mjs";
import { StatsManager } from "./StatsManager.mjs";
import { PLUGIN_IDENTIFIER } from "./constants.mjs";
import logger from "./logger.mjs";
;// CONCATENATED MODULE: external "@module-federation/sdk"
;// CONCATENATED MODULE: external "./ManifestManager.mjs"
;// CONCATENATED MODULE: external "./StatsManager.mjs"
;// CONCATENATED MODULE: external "./constants.mjs"
;// CONCATENATED MODULE: external "./logger.mjs"
;// CONCATENATED MODULE: ./src/StatsPlugin.ts
class StatsPlugin {
apply(compiler) {
bindLoggerToCompiler(logger, compiler, PLUGIN_IDENTIFIER);
if (!this._enable) {
return;
}
const res = this._statsManager.validate(compiler);
if (!res) {
return;
}
compiler.hooks.thisCompilation.tap('generateStats', (compilation)=>{
compilation.hooks.processAssets.tapPromise({
name: 'generateStats',
// @ts-ignore use runtime variable in case peer dep not installed
stage: compilation.constructor.PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER
}, async ()=>{
if (this._options.manifest !== false) {
const existedStats = compilation.getAsset(this._statsManager.fileName);
// new rspack should hit
if (existedStats) {
let updatedStats = this._statsManager.updateStats(JSON.parse(existedStats.source.source().toString()), compiler);
if (typeof this._options.manifest === 'object' && this._options.manifest.additionalData) {
updatedStats = await this._options.manifest.additionalData({
stats: updatedStats,
compiler,
compilation,
bundler: this._bundler
}) || updatedStats;
}
compilation.updateAsset(this._statsManager.fileName, new compiler.webpack.sources.RawSource(JSON.stringify(updatedStats, null, 2)));
const updatedManifest = this._manifestManager.updateManifest({
compilation,
stats: updatedStats,
publicPath: this._statsManager.getPublicPath(compiler),
compiler,
bundler: this._bundler
});
const source = new compiler.webpack.sources.RawSource(JSON.stringify(updatedManifest, null, 2));
compilation.updateAsset(this._manifestManager.fileName, source);
return;
}
// webpack + legacy rspack
let stats = await this._statsManager.generateStats(compiler, compilation);
if (typeof this._options.manifest === 'object' && this._options.manifest.additionalData) {
stats = await this._options.manifest.additionalData({
stats,
compiler,
compilation,
bundler: this._bundler
}) || stats;
}
const manifest = await this._manifestManager.generateManifest({
compilation,
stats: stats,
publicPath: this._statsManager.getPublicPath(compiler),
compiler,
bundler: this._bundler
});
compilation.emitAsset(this._statsManager.fileName, new compiler.webpack.sources.RawSource(JSON.stringify(stats, null, 2)));
compilation.emitAsset(this._manifestManager.fileName, new compiler.webpack.sources.RawSource(JSON.stringify(manifest, null, 2)));
}
});
});
}
constructor(options, { pluginVersion, bundler }){
this.name = 'StatsPlugin';
this._options = {};
this._statsManager = new StatsManager();
this._manifestManager = new ManifestManager();
this._enable = true;
this._bundler = 'webpack';
try {
this._options = options;
this._bundler = bundler;
this._statsManager.init(this._options, {
pluginVersion,
bundler
});
this._manifestManager.init(this._options);
} catch (err) {
if (err instanceof Error) {
err.message = `[ ${PLUGIN_IDENTIFIER} ]: Manifest will not generate, because: ${err.message}`;
}
logger.error(err);
this._enable = false;
}
}
}
export { StatsPlugin };

View File

@@ -0,0 +1,2 @@
export declare const PLUGIN_IDENTIFIER = "Module Federation Manifest Plugin";
export declare const HOT_UPDATE_SUFFIX = ".hot-update";

View File

@@ -0,0 +1,54 @@
"use strict";
const __rslib_import_meta_url__ = /*#__PURE__*/ (function () {
return typeof document === 'undefined'
? new (require('url'.replace('', '')).URL)('file:' + __filename).href
: (document.currentScript && document.currentScript.src) ||
new URL('main.js', document.baseURI).href;
})();
;
// The require scope
var __webpack_require__ = {};
/************************************************************************/
// webpack/runtime/define_property_getters
(() => {
__webpack_require__.d = (exports, definition) => {
for(var key in definition) {
if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
}
}
};
})();
// webpack/runtime/has_own_property
(() => {
__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
})();
// webpack/runtime/make_namespace_object
(() => {
// define __esModule on exports
__webpack_require__.r = (exports) => {
if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
}
Object.defineProperty(exports, '__esModule', { value: true });
};
})();
/************************************************************************/
var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
HOT_UPDATE_SUFFIX: () => (HOT_UPDATE_SUFFIX),
PLUGIN_IDENTIFIER: () => (PLUGIN_IDENTIFIER)
});
const PLUGIN_IDENTIFIER = 'Module Federation Manifest Plugin';
const HOT_UPDATE_SUFFIX = '.hot-update';
exports.HOT_UPDATE_SUFFIX = __webpack_exports__.HOT_UPDATE_SUFFIX;
exports.PLUGIN_IDENTIFIER = __webpack_exports__.PLUGIN_IDENTIFIER;
for(var __webpack_i__ in __webpack_exports__) {
if(["HOT_UPDATE_SUFFIX","PLUGIN_IDENTIFIER"].indexOf(__webpack_i__) === -1) {
exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
}
}
Object.defineProperty(exports, '__esModule', { value: true });

View File

@@ -0,0 +1,6 @@
;// CONCATENATED MODULE: ./src/constants.ts
const PLUGIN_IDENTIFIER = 'Module Federation Manifest Plugin';
const HOT_UPDATE_SUFFIX = '.hot-update';
export { HOT_UPDATE_SUFFIX, PLUGIN_IDENTIFIER };

View File

@@ -0,0 +1,4 @@
export { StatsPlugin } from './StatsPlugin';
export { ManifestManager } from './ManifestManager';
export { StatsManager } from './StatsManager';
export * from './types';

126
node_modules/@module-federation/manifest/dist/index.js generated vendored Normal file
View File

@@ -0,0 +1,126 @@
"use strict";
const __rslib_import_meta_url__ = /*#__PURE__*/ (function () {
return typeof document === 'undefined'
? new (require('url'.replace('', '')).URL)('file:' + __filename).href
: (document.currentScript && document.currentScript.src) ||
new URL('main.js', document.baseURI).href;
})();
;
var __webpack_modules__ = ({
"./ManifestManager": (function (module) {
module.exports = require("./ManifestManager.js");
}),
"./StatsManager": (function (module) {
module.exports = require("./StatsManager.js");
}),
"./StatsPlugin": (function (module) {
module.exports = require("./StatsPlugin.js");
}),
"./types": (function (module) {
module.exports = require("./types.js");
}),
});
/************************************************************************/
// The module cache
var __webpack_module_cache__ = {};
// The require function
function __webpack_require__(moduleId) {
// Check if module is in cache
var cachedModule = __webpack_module_cache__[moduleId];
if (cachedModule !== undefined) {
return cachedModule.exports;
}
// Create a new module (and put it into the cache)
var module = (__webpack_module_cache__[moduleId] = {
exports: {}
});
// Execute the module function
__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
// Return the exports of the module
return module.exports;
}
/************************************************************************/
// webpack/runtime/compat_get_default_export
(() => {
// getDefaultExport function for compatibility with non-ESM modules
__webpack_require__.n = (module) => {
var getter = module && module.__esModule ?
() => (module['default']) :
() => (module);
__webpack_require__.d(getter, { a: getter });
return getter;
};
})();
// webpack/runtime/define_property_getters
(() => {
__webpack_require__.d = (exports, definition) => {
for(var key in definition) {
if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
}
}
};
})();
// webpack/runtime/has_own_property
(() => {
__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
})();
// webpack/runtime/make_namespace_object
(() => {
// define __esModule on exports
__webpack_require__.r = (exports) => {
if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
}
Object.defineProperty(exports, '__esModule', { value: true });
};
})();
/************************************************************************/
var __webpack_exports__ = {};
// This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
(() => {
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
ManifestManager: () => (/* reexport safe */ _ManifestManager__WEBPACK_IMPORTED_MODULE_1__.ManifestManager),
StatsManager: () => (/* reexport safe */ _StatsManager__WEBPACK_IMPORTED_MODULE_2__.StatsManager),
StatsPlugin: () => (/* reexport safe */ _StatsPlugin__WEBPACK_IMPORTED_MODULE_0__.StatsPlugin)
});
/* ESM import */var _StatsPlugin__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./StatsPlugin");
/* ESM import */var _StatsPlugin__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_StatsPlugin__WEBPACK_IMPORTED_MODULE_0__);
/* ESM import */var _ManifestManager__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./ManifestManager");
/* ESM import */var _ManifestManager__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_ManifestManager__WEBPACK_IMPORTED_MODULE_1__);
/* ESM import */var _StatsManager__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./StatsManager");
/* ESM import */var _StatsManager__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_StatsManager__WEBPACK_IMPORTED_MODULE_2__);
/* ESM import */var _types__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./types");
/* ESM import */var _types__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_types__WEBPACK_IMPORTED_MODULE_3__);
/* ESM reexport (unknown) */ var __WEBPACK_REEXPORT_OBJECT__ = {};
/* ESM reexport (unknown) */ for( var __WEBPACK_IMPORT_KEY__ in _types__WEBPACK_IMPORTED_MODULE_3__) if(["StatsManager","default","ManifestManager","StatsPlugin"].indexOf(__WEBPACK_IMPORT_KEY__) < 0) __WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] =function(key) { return _types__WEBPACK_IMPORTED_MODULE_3__[key]; }.bind(0, __WEBPACK_IMPORT_KEY__)
/* ESM reexport (unknown) */ __webpack_require__.d(__webpack_exports__, __WEBPACK_REEXPORT_OBJECT__);
})();
exports.ManifestManager = __webpack_exports__.ManifestManager;
exports.StatsManager = __webpack_exports__.StatsManager;
exports.StatsPlugin = __webpack_exports__.StatsPlugin;
for(var __webpack_i__ in __webpack_exports__) {
if(["ManifestManager","StatsManager","StatsPlugin"].indexOf(__webpack_i__) === -1) {
exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
}
}
Object.defineProperty(exports, '__esModule', { value: true });

View File

@@ -0,0 +1,18 @@
import { StatsPlugin } from "./StatsPlugin.mjs";
import { ManifestManager } from "./ManifestManager.mjs";
import { StatsManager } from "./StatsManager.mjs";
export * from "./types.mjs";
;// CONCATENATED MODULE: external "./StatsPlugin.mjs"
;// CONCATENATED MODULE: external "./ManifestManager.mjs"
;// CONCATENATED MODULE: external "./StatsManager.mjs"
;// CONCATENATED MODULE: ./src/index.ts
export { ManifestManager, StatsManager, StatsPlugin };

View File

@@ -0,0 +1,2 @@
declare const logger: import("@module-federation/sdk").Logger;
export default logger;

View File

@@ -0,0 +1,67 @@
"use strict";
const __rslib_import_meta_url__ = /*#__PURE__*/ (function () {
return typeof document === 'undefined'
? new (require('url'.replace('', '')).URL)('file:' + __filename).href
: (document.currentScript && document.currentScript.src) ||
new URL('main.js', document.baseURI).href;
})();
;
// The require scope
var __webpack_require__ = {};
/************************************************************************/
// webpack/runtime/define_property_getters
(() => {
__webpack_require__.d = (exports, definition) => {
for(var key in definition) {
if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
}
}
};
})();
// webpack/runtime/has_own_property
(() => {
__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
})();
// webpack/runtime/make_namespace_object
(() => {
// define __esModule on exports
__webpack_require__.r = (exports) => {
if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
}
Object.defineProperty(exports, '__esModule', { value: true });
};
})();
/************************************************************************/
var __webpack_exports__ = {};
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
"default": () => (/* binding */ src_logger)
});
;// CONCATENATED MODULE: external "node:util"
const external_node_util_namespaceObject = require("node:util");
;// CONCATENATED MODULE: external "@module-federation/sdk"
const sdk_namespaceObject = require("@module-federation/sdk");
;// CONCATENATED MODULE: external "./constants.js"
const external_constants_js_namespaceObject = require("./constants.js");
;// CONCATENATED MODULE: ./src/logger.ts
const createBundlerLogger = typeof sdk_namespaceObject.createInfrastructureLogger === 'function' ? sdk_namespaceObject.createInfrastructureLogger : sdk_namespaceObject.createLogger;
const logger = createBundlerLogger((0,external_node_util_namespaceObject.styleText)('cyan', `[ ${external_constants_js_namespaceObject.PLUGIN_IDENTIFIER} ]`));
/* ESM default export */ const src_logger = (logger);
exports["default"] = __webpack_exports__["default"];
for(var __webpack_i__ in __webpack_exports__) {
if(["default"].indexOf(__webpack_i__) === -1) {
exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
}
}
Object.defineProperty(exports, '__esModule', { value: true });

View File

@@ -0,0 +1,19 @@
import { styleText } from "node:util";
import { createInfrastructureLogger, createLogger } from "@module-federation/sdk";
import { PLUGIN_IDENTIFIER } from "./constants.mjs";
;// CONCATENATED MODULE: external "node:util"
;// CONCATENATED MODULE: external "@module-federation/sdk"
;// CONCATENATED MODULE: external "./constants.mjs"
;// CONCATENATED MODULE: ./src/logger.ts
const createBundlerLogger = typeof createInfrastructureLogger === 'function' ? createInfrastructureLogger : createLogger;
const logger = createBundlerLogger(styleText('cyan', `[ ${PLUGIN_IDENTIFIER} ]`));
/* ESM default export */ const src_logger = (logger);
export { src_logger as default };

View File

@@ -0,0 +1,13 @@
import { Manifest, Stats } from '@module-federation/sdk';
export type StatsInfo = {
stats: Stats;
filename: string;
};
export type ManifestInfo = {
manifest: Manifest;
filename: string;
};
export type ResourceInfo = {
stats: StatsInfo;
manifest: ManifestInfo;
};

31
node_modules/@module-federation/manifest/dist/types.js generated vendored Normal file
View File

@@ -0,0 +1,31 @@
"use strict";
const __rslib_import_meta_url__ = /*#__PURE__*/ (function () {
return typeof document === 'undefined'
? new (require('url'.replace('', '')).URL)('file:' + __filename).href
: (document.currentScript && document.currentScript.src) ||
new URL('main.js', document.baseURI).href;
})();
;
// The require scope
var __webpack_require__ = {};
/************************************************************************/
// webpack/runtime/make_namespace_object
(() => {
// define __esModule on exports
__webpack_require__.r = (exports) => {
if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
}
Object.defineProperty(exports, '__esModule', { value: true });
};
})();
/************************************************************************/
var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
for(var __webpack_i__ in __webpack_exports__) {
exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
}
Object.defineProperty(exports, '__esModule', { value: true });

View File

@@ -0,0 +1,4 @@
;// CONCATENATED MODULE: ./src/types.ts

View File

@@ -0,0 +1,15 @@
import { Chunk, Compilation } from 'webpack';
import type { StatsCompilation, StatsModule } from '../../../webpack/lib/stats/DefaultStatsFactoryPlugin.d';
import { StatsAssets, moduleFederationPlugin, MetaDataTypes } from '@module-federation/sdk';
export declare function getAssetsByChunkIDs(compilation: Compilation, chunkIDMap: Record<string, Set<string | number>>): Record<string, {
js: string[];
css: string[];
}>;
export declare function findChunk(id: string | number, chunks: Set<Chunk>): Chunk | void;
export declare function getSharedModules(stats: StatsCompilation, sharedModules: StatsModule[]): [string, StatsModule][];
export declare function getAssetsByChunk(chunk: Chunk, entryPointNames: Array<string>): StatsAssets;
export declare function assert(condition: any, msg: string): asserts condition;
export declare function error(msg: string | Error | unknown): never;
export declare function isDev(): boolean;
export declare function getFileNameWithOutExt(str: string): string;
export declare function getTypesMetaInfo(pluginOptions: moduleFederationPlugin.ModuleFederationPluginOptions, context: string): MetaDataTypes;

296
node_modules/@module-federation/manifest/dist/utils.js generated vendored Normal file
View File

@@ -0,0 +1,296 @@
"use strict";
const __rslib_import_meta_url__ = /*#__PURE__*/ (function () {
return typeof document === 'undefined'
? new (require('url'.replace('', '')).URL)('file:' + __filename).href
: (document.currentScript && document.currentScript.src) ||
new URL('main.js', document.baseURI).href;
})();
;
// The require scope
var __webpack_require__ = {};
/************************************************************************/
// webpack/runtime/compat_get_default_export
(() => {
// getDefaultExport function for compatibility with non-ESM modules
__webpack_require__.n = (module) => {
var getter = module && module.__esModule ?
() => (module['default']) :
() => (module);
__webpack_require__.d(getter, { a: getter });
return getter;
};
})();
// webpack/runtime/define_property_getters
(() => {
__webpack_require__.d = (exports, definition) => {
for(var key in definition) {
if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
}
}
};
})();
// webpack/runtime/has_own_property
(() => {
__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
})();
// webpack/runtime/make_namespace_object
(() => {
// define __esModule on exports
__webpack_require__.r = (exports) => {
if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
}
Object.defineProperty(exports, '__esModule', { value: true });
};
})();
/************************************************************************/
var __webpack_exports__ = {};
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
findChunk: () => (/* binding */ findChunk),
getSharedModules: () => (/* binding */ getSharedModules),
getTypesMetaInfo: () => (/* binding */ getTypesMetaInfo),
isDev: () => (/* binding */ isDev),
getFileNameWithOutExt: () => (/* binding */ getFileNameWithOutExt),
getAssetsByChunk: () => (/* binding */ getAssetsByChunk),
error: () => (/* binding */ error),
getAssetsByChunkIDs: () => (/* binding */ getAssetsByChunkIDs),
assert: () => (/* binding */ assert)
});
;// CONCATENATED MODULE: external "path"
const external_path_namespaceObject = require("path");
var external_path_default = /*#__PURE__*/__webpack_require__.n(external_path_namespaceObject);
;// CONCATENATED MODULE: external "@module-federation/sdk"
const sdk_namespaceObject = require("@module-federation/sdk");
;// CONCATENATED MODULE: external "@module-federation/dts-plugin/core"
const core_namespaceObject = require("@module-federation/dts-plugin/core");
;// CONCATENATED MODULE: external "./constants.js"
const external_constants_js_namespaceObject = require("./constants.js");
;// CONCATENATED MODULE: external "./logger.js"
const external_logger_js_namespaceObject = require("./logger.js");
var external_logger_js_default = /*#__PURE__*/__webpack_require__.n(external_logger_js_namespaceObject);
;// CONCATENATED MODULE: ./src/utils.ts
function isHotFile(file) {
return file.includes(external_constants_js_namespaceObject.HOT_UPDATE_SUFFIX);
}
const collectAssets = (assets, jsTargetSet, cssTargetSet)=>{
assets.forEach((file)=>{
if (file.endsWith('.css')) {
cssTargetSet.add(file);
} else {
if (isDev()) {
if (!isHotFile(file)) {
jsTargetSet.add(file);
}
} else {
jsTargetSet.add(file);
}
}
});
};
function getSharedModuleName(name) {
const [_type, _shared, _module, _shareScope, sharedInfo] = name.split(' ');
return sharedInfo.split('@').slice(0, -1).join('@');
}
function getAssetsByChunkIDs(compilation, chunkIDMap) {
const arrayChunks = Array.from(compilation.chunks);
const assetMap = {};
Object.keys(chunkIDMap).forEach((key)=>{
const chunkIDs = Array.from(chunkIDMap[key]);
if (!assetMap[key]) {
assetMap[key] = {
css: new Set(),
js: new Set()
};
}
chunkIDs.forEach((chunkID)=>{
const chunk = arrayChunks.find((item)=>item.id === chunkID);
if (chunk) {
collectAssets([
...chunk.files
], assetMap[key].js, assetMap[key].css);
}
});
});
const assets = {};
Object.keys(assetMap).map((key)=>{
assets[key] = {
js: Array.from(assetMap[key].js),
css: Array.from(assetMap[key].css)
};
});
return assets;
}
function findChunk(id, chunks) {
for (const chunk of chunks){
if (id === chunk.id) {
return chunk;
}
}
}
function getSharedModules(stats, sharedModules) {
var _stats_modules;
// 获取入口文件就是实际内容的 module
const entryContentModuleNames = [];
let effectiveSharedModules = ((_stats_modules = stats.modules) === null || _stats_modules === void 0 ? void 0 : _stats_modules.reduce((sum, module)=>{
for (const sharedModule of sharedModules){
if (sharedModule.name === module.issuerName) {
entryContentModuleNames.push(sharedModule.name);
sum.push([
getSharedModuleName(module.issuerName),
module
]);
return sum;
}
}
return sum;
}, [])) || [];
// 获取入口文件仅作为 Re Export 的 module
const entryReExportModules = sharedModules.filter((sharedModule)=>!entryContentModuleNames.includes(sharedModule.name));
if (entryReExportModules.length) {
effectiveSharedModules = effectiveSharedModules.concat(stats.modules.reduce((sum, module)=>{
let flag = false;
for (const entryReExportModule of entryReExportModules){
if (flag) {
break;
}
if (module.reasons) {
for (const issueModule of module.reasons){
if (issueModule.moduleName === entryReExportModule.name) {
sum.push([
getSharedModuleName(entryReExportModule.name),
module
]);
flag = true;
break;
}
}
}
}
return sum;
}, []));
}
return effectiveSharedModules;
}
function getAssetsByChunk(chunk, entryPointNames) {
const assesSet = {
js: {
sync: new Set(),
async: new Set()
},
css: {
sync: new Set(),
async: new Set()
}
};
const collectChunkFiles = (targetChunk, type)=>{
[
...targetChunk.groupsIterable
].forEach((chunkGroup)=>{
if (chunkGroup.name && !entryPointNames.includes(chunkGroup.name)) {
collectAssets(chunkGroup.getFiles(), assesSet.js[type], assesSet.css[type]);
}
});
};
collectChunkFiles(chunk, 'sync');
[
...chunk.getAllAsyncChunks()
].forEach((asyncChunk)=>{
collectAssets([
...asyncChunk.files
], assesSet.js['async'], assesSet.css['async']);
collectChunkFiles(asyncChunk, 'async');
});
const assets = {
js: {
sync: Array.from(assesSet.js.sync),
async: Array.from(assesSet.js.async)
},
css: {
sync: Array.from(assesSet.css.sync),
async: Array.from(assesSet.css.async)
}
};
return assets;
}
function assert(condition, msg) {
if (!condition) {
error(msg);
}
}
function error(msg) {
throw new Error(`[ ${external_constants_js_namespaceObject.PLUGIN_IDENTIFIER} ]: ${msg}`);
}
function isDev() {
return process.env['NODE_ENV'] === 'development';
}
function getFileNameWithOutExt(str) {
return str.replace(external_path_default().extname(str), '');
}
function getTypesMetaInfo(pluginOptions, context) {
const defaultRemoteOptions = {
generateAPITypes: true,
compileInChildProcess: true
};
const defaultTypesMetaInfo = {
path: '',
name: '',
zip: '',
api: ''
};
try {
const normalizedDtsOptions = (0,sdk_namespaceObject.normalizeOptions)((0,core_namespaceObject.isTSProject)(pluginOptions.dts, context), {
generateTypes: defaultRemoteOptions,
consumeTypes: {}
}, 'mfOptions.dts')(pluginOptions.dts);
if (normalizedDtsOptions === false) {
return defaultTypesMetaInfo;
}
const normalizedRemote = (0,sdk_namespaceObject.normalizeOptions)(true, defaultRemoteOptions, 'mfOptions.dts.generateTypes')(normalizedDtsOptions.generateTypes);
if (normalizedRemote === false) {
return defaultTypesMetaInfo;
}
const { apiFileName, zipName } = (0,core_namespaceObject.retrieveTypesAssetsInfo)({
...normalizedRemote,
context,
moduleFederationConfig: pluginOptions
});
return {
path: '',
name: '',
zip: zipName,
api: apiFileName
};
} catch (err) {
external_logger_js_default().warn(`getTypesMetaInfo failed, it will use the default types meta info, and the errors as belows: ${err}`);
return defaultTypesMetaInfo;
}
}
exports.assert = __webpack_exports__.assert;
exports.error = __webpack_exports__.error;
exports.findChunk = __webpack_exports__.findChunk;
exports.getAssetsByChunk = __webpack_exports__.getAssetsByChunk;
exports.getAssetsByChunkIDs = __webpack_exports__.getAssetsByChunkIDs;
exports.getFileNameWithOutExt = __webpack_exports__.getFileNameWithOutExt;
exports.getSharedModules = __webpack_exports__.getSharedModules;
exports.getTypesMetaInfo = __webpack_exports__.getTypesMetaInfo;
exports.isDev = __webpack_exports__.isDev;
for(var __webpack_i__ in __webpack_exports__) {
if(["assert","error","findChunk","getAssetsByChunk","getAssetsByChunkIDs","getFileNameWithOutExt","getSharedModules","getTypesMetaInfo","isDev"].indexOf(__webpack_i__) === -1) {
exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
}
}
Object.defineProperty(exports, '__esModule', { value: true });

220
node_modules/@module-federation/manifest/dist/utils.mjs generated vendored Normal file
View File

@@ -0,0 +1,220 @@
import path from "path";
import { normalizeOptions } from "@module-federation/sdk";
import { isTSProject, retrieveTypesAssetsInfo } from "@module-federation/dts-plugin/core";
import { HOT_UPDATE_SUFFIX, PLUGIN_IDENTIFIER } from "./constants.mjs";
import logger from "./logger.mjs";
;// CONCATENATED MODULE: external "path"
;// CONCATENATED MODULE: external "@module-federation/sdk"
;// CONCATENATED MODULE: external "@module-federation/dts-plugin/core"
;// CONCATENATED MODULE: external "./constants.mjs"
;// CONCATENATED MODULE: external "./logger.mjs"
;// CONCATENATED MODULE: ./src/utils.ts
function isHotFile(file) {
return file.includes(HOT_UPDATE_SUFFIX);
}
const collectAssets = (assets, jsTargetSet, cssTargetSet)=>{
assets.forEach((file)=>{
if (file.endsWith('.css')) {
cssTargetSet.add(file);
} else {
if (isDev()) {
if (!isHotFile(file)) {
jsTargetSet.add(file);
}
} else {
jsTargetSet.add(file);
}
}
});
};
function getSharedModuleName(name) {
const [_type, _shared, _module, _shareScope, sharedInfo] = name.split(' ');
return sharedInfo.split('@').slice(0, -1).join('@');
}
function getAssetsByChunkIDs(compilation, chunkIDMap) {
const arrayChunks = Array.from(compilation.chunks);
const assetMap = {};
Object.keys(chunkIDMap).forEach((key)=>{
const chunkIDs = Array.from(chunkIDMap[key]);
if (!assetMap[key]) {
assetMap[key] = {
css: new Set(),
js: new Set()
};
}
chunkIDs.forEach((chunkID)=>{
const chunk = arrayChunks.find((item)=>item.id === chunkID);
if (chunk) {
collectAssets([
...chunk.files
], assetMap[key].js, assetMap[key].css);
}
});
});
const assets = {};
Object.keys(assetMap).map((key)=>{
assets[key] = {
js: Array.from(assetMap[key].js),
css: Array.from(assetMap[key].css)
};
});
return assets;
}
function findChunk(id, chunks) {
for (const chunk of chunks){
if (id === chunk.id) {
return chunk;
}
}
}
function getSharedModules(stats, sharedModules) {
var _stats_modules;
// 获取入口文件就是实际内容的 module
const entryContentModuleNames = [];
let effectiveSharedModules = ((_stats_modules = stats.modules) === null || _stats_modules === void 0 ? void 0 : _stats_modules.reduce((sum, module)=>{
for (const sharedModule of sharedModules){
if (sharedModule.name === module.issuerName) {
entryContentModuleNames.push(sharedModule.name);
sum.push([
getSharedModuleName(module.issuerName),
module
]);
return sum;
}
}
return sum;
}, [])) || [];
// 获取入口文件仅作为 Re Export 的 module
const entryReExportModules = sharedModules.filter((sharedModule)=>!entryContentModuleNames.includes(sharedModule.name));
if (entryReExportModules.length) {
effectiveSharedModules = effectiveSharedModules.concat(stats.modules.reduce((sum, module)=>{
let flag = false;
for (const entryReExportModule of entryReExportModules){
if (flag) {
break;
}
if (module.reasons) {
for (const issueModule of module.reasons){
if (issueModule.moduleName === entryReExportModule.name) {
sum.push([
getSharedModuleName(entryReExportModule.name),
module
]);
flag = true;
break;
}
}
}
}
return sum;
}, []));
}
return effectiveSharedModules;
}
function getAssetsByChunk(chunk, entryPointNames) {
const assesSet = {
js: {
sync: new Set(),
async: new Set()
},
css: {
sync: new Set(),
async: new Set()
}
};
const collectChunkFiles = (targetChunk, type)=>{
[
...targetChunk.groupsIterable
].forEach((chunkGroup)=>{
if (chunkGroup.name && !entryPointNames.includes(chunkGroup.name)) {
collectAssets(chunkGroup.getFiles(), assesSet.js[type], assesSet.css[type]);
}
});
};
collectChunkFiles(chunk, 'sync');
[
...chunk.getAllAsyncChunks()
].forEach((asyncChunk)=>{
collectAssets([
...asyncChunk.files
], assesSet.js['async'], assesSet.css['async']);
collectChunkFiles(asyncChunk, 'async');
});
const assets = {
js: {
sync: Array.from(assesSet.js.sync),
async: Array.from(assesSet.js.async)
},
css: {
sync: Array.from(assesSet.css.sync),
async: Array.from(assesSet.css.async)
}
};
return assets;
}
function assert(condition, msg) {
if (!condition) {
error(msg);
}
}
function error(msg) {
throw new Error(`[ ${PLUGIN_IDENTIFIER} ]: ${msg}`);
}
function isDev() {
return process.env['NODE_ENV'] === 'development';
}
function getFileNameWithOutExt(str) {
return str.replace(path.extname(str), '');
}
function getTypesMetaInfo(pluginOptions, context) {
const defaultRemoteOptions = {
generateAPITypes: true,
compileInChildProcess: true
};
const defaultTypesMetaInfo = {
path: '',
name: '',
zip: '',
api: ''
};
try {
const normalizedDtsOptions = normalizeOptions(isTSProject(pluginOptions.dts, context), {
generateTypes: defaultRemoteOptions,
consumeTypes: {}
}, 'mfOptions.dts')(pluginOptions.dts);
if (normalizedDtsOptions === false) {
return defaultTypesMetaInfo;
}
const normalizedRemote = normalizeOptions(true, defaultRemoteOptions, 'mfOptions.dts.generateTypes')(normalizedDtsOptions.generateTypes);
if (normalizedRemote === false) {
return defaultTypesMetaInfo;
}
const { apiFileName, zipName } = retrieveTypesAssetsInfo({
...normalizedRemote,
context,
moduleFederationConfig: pluginOptions
});
return {
path: '',
name: '',
zip: zipName,
api: apiFileName
};
} catch (err) {
logger.warn(`getTypesMetaInfo failed, it will use the default types meta info, and the errors as belows: ${err}`);
return defaultTypesMetaInfo;
}
}
export { assert, error, findChunk, getAssetsByChunk, getAssetsByChunkIDs, getFileNameWithOutExt, getSharedModules, getTypesMetaInfo, isDev };

64
node_modules/@module-federation/manifest/package.json generated vendored Normal file
View File

@@ -0,0 +1,64 @@
{
"name": "@module-federation/manifest",
"version": "2.5.0",
"license": "MIT",
"description": "Provide manifest/stats for webpack/rspack MF project .",
"keywords": [
"Module Federation",
"Webpack",
"Rspack",
"Manifest"
],
"files": [
"dist/",
"README.md"
],
"publishConfig": {
"access": "public"
},
"author": "hanric <hanric.zhang@gmail.com>",
"repository": {
"type": "git",
"url": "git+https://github.com/module-federation/core.git",
"directory": "packages/manifest"
},
"sideEffects": false,
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"dependencies": {
"find-pkg": "2.0.0",
"@module-federation/sdk": "2.5.0",
"@module-federation/dts-plugin": "2.5.0",
"@module-federation/managers": "2.5.0"
},
"exports": {
".": {
"import": {
"types": "./dist/index.d.ts",
"default": "./dist/index.mjs"
},
"require": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
}
}
},
"typesVersions": {
"*": {
".": [
"./dist/index.d.ts"
]
}
},
"devDependencies": {
"webpack": "^5.0.0"
},
"scripts": {
"build": "rslib build",
"lint": "ESLINT_USE_FLAT_CONFIG=false pnpm exec eslint --ignore-pattern node_modules \"**/*.ts\" \"package.json\"",
"test": "pnpm exec jest --config jest.config.js --passWithNoTests",
"test:ci": "pnpm exec jest --config jest.config.js --passWithNoTests --ci --coverage",
"pre-release": "pnpm run test && pnpm run build"
}
}