UNPKG

zephyr-xpack-internal

Version:

Xpack internals for Zephyr

174 lines (173 loc) • 8.87 kB
import __rslib_shim_module__ from "node:module"; const require = /*#__PURE__*/ __rslib_shim_module__.createRequire(/*#__PURE__*/ (()=>import.meta.url)()); import { dirname, resolve, sep } from "node:path"; import { ZeErrors } from "zephyr-agent"; import { extractFederatedConfig, isModuleFederationPlugin, parseRemotesAsEntries } from "../../../xpack-extract/index.mjs"; import { convertToGraph } from "../convert-to-graph/convert-to-graph.mjs"; import { AddRuntimeRequirementToPromiseExternal } from "./add-runtime-requirement-to-promise-external.mjs"; import { computeVersionStrategy, gitSha } from "./compute-version-strategy.mjs"; import { buildVersionedDependencyMap, findPackageJson, resolveInstalledPackageVersion } from "./find-package-json.mjs"; import { __webpack_require__ } from "../../../rslib-runtime~0.mjs"; import { createRequire as __rspack_createRequire } from "node:module"; const __rspack_createRequire_require = __rspack_createRequire(import.meta.url); __webpack_require__.add({ "node:module" (module) { module.exports = __rspack_createRequire_require("node:module"); } }); const { createRequire: createProjectRequire } = __webpack_require__("node:module"); function resolveFederationGraphConfiguration(mfConfig, fallback, applicationName) { const plugins = mfConfig ? Array.isArray(mfConfig) ? mfConfig : [ mfConfig ] : []; const configurations = plugins.flatMap((plugin)=>{ const config = extractFederatedConfig(plugin); return config ? [ config ] : []; }); const resolvedConfigurations = configurations.length > 0 ? configurations : Object.keys(fallback).length > 0 ? [ fallback ] : []; const remoteNames = [ ...new Set(resolvedConfigurations.flatMap((config)=>parseRemotesAsEntries(config.remotes).map(([remoteName])=>remoteName))) ]; return { configurations: resolvedConfigurations, graphConfiguration: 1 === resolvedConfigurations.length ? resolvedConfigurations[0] : { name: applicationName }, remoteNames }; } class FederationDashboardPlugin { _options; _dashData; allArgumentsUsed = []; FederationPluginOptions = {}; constructor(options){ this._options = Object.assign({ debug: false, useAST: false }, options); } apply(compiler) { compiler.options.output.uniqueName = `v${Date.now()}`; new AddRuntimeRequirementToPromiseExternal().apply(compiler); const FederationPlugin = compiler.options.plugins.find(isModuleFederationPlugin); this._options.standalone = void 0 === FederationPlugin; if (FederationPlugin) this.FederationPluginOptions = Object.assign({}, extractFederatedConfig(FederationPlugin), this._options.standalone || {}); else if (this._options.standalone) this.FederationPluginOptions = {}; else throw new Error('Dashboard plugin is missing Module Federation or standalone option'); } processWebpackGraph({ stats, stats_json, pluginOptions }) { const { configurations, graphConfiguration, remoteNames } = resolveFederationGraphConfiguration(pluginOptions.mfConfig, this.FederationPluginOptions, this._options.app?.name); this.FederationPluginOptions = graphConfiguration; const remoteEntryChunk = 1 === configurations.length ? this.getRemoteEntryChunk(stats_json, graphConfiguration) : void 0; const validChunkArray = Array.from(new Set(configurations.flatMap((configuration)=>this.buildValidChunkArray(stats, configuration)))); const chunkDependencies = this.getChunkDependencies(validChunkArray); const vendorFederation = this.buildVendorFederationMap(stats); const getPlatformFromStats = stats.compilation.name; const rawData = { name: graphConfiguration.name, filename: graphConfiguration.filename || '', remotes: remoteNames, metadata: Object.assign({}, this._options.metadata, this.attach_remote_bundle_name_to_metadata(configurations)) || {}, topLevelPackage: vendorFederation || {}, publicPath: stats_json.publicPath, federationRemoteEntry: remoteEntryChunk, buildHash: stats_json.hash, environment: this._options.environment || 'development', version: computeVersionStrategy(stats_json, this._options.versionStrategy), posted: this._options.posted || new Date(), group: this._options.group || 'default', sha: gitSha, modules: stats_json.modules, chunkDependencies, functionRemotes: this.allArgumentsUsed, target: pluginOptions.target ?? pluginOptions.zephyr_engine.env.target ?? getPlatformFromStats }; let graphData; try { graphData = convertToGraph(rawData); } catch (err) { console.warn('Error during dashboard data processing'); console.warn(err); } if (!graphData) return; return graphData; } getRemoteEntryChunk(stats, FederationPluginOptions) { if (!stats.chunks) return; return stats.chunks.find((chunk)=>chunk.names?.find((name)=>name === FederationPluginOptions.name)); } getChunkDependencies(validChunkArray) { return validChunkArray.reduce((acc, chunk)=>{ const subset = chunk.getAllReferencedChunks(); const stringifiableChunk = Array.from(subset).map((sub)=>{ const cleanSet = Object.getOwnPropertyNames(sub).reduce((acc, key)=>{ if ('_groups' === key) return acc; return Object.assign(acc, { [key]: sub[key] }); }, {}); return this.mapToObjectRec(cleanSet); }); return Object.assign(acc, { [`${chunk.id}`]: stringifiableChunk }); }, {}); } buildVendorFederationMap(liveStats) { const vendorFederation = {}; let packageJson; if (this._options.packageJsonPath) try { packageJson = require(this._options.packageJsonPath); } catch (error) { console.warn(`Unable to read package JSON at ${this._options.packageJsonPath}: ${String(error)}`); } else { const initialPath = liveStats.compilation.options.context?.split(sep); packageJson = findPackageJson(initialPath); } if (packageJson) { const resolveFrom = this._options.packageJsonPath ? dirname(this._options.packageJsonPath) : liveStats.compilation.options.context ?? process.cwd(); const projectRequire = createProjectRequire(resolve(resolveFrom, 'package.json')); const resolveVersion = (packageName)=>resolveInstalledPackageVersion(packageName, projectRequire); vendorFederation.dependencies = buildVersionedDependencyMap(packageJson, 'dependencies', resolveVersion); vendorFederation.devDependencies = buildVersionedDependencyMap(packageJson, 'devDependencies', resolveVersion); vendorFederation.optionalDependencies = buildVersionedDependencyMap(packageJson, 'optionalDependencies', resolveVersion); } return vendorFederation; } mapToObjectRec(m) { const lo = {}; for (const [key, value] of Object.entries(m))if (value instanceof Map && value.size > 0) lo[key] = this.mapToObjectRec(value); else if (value instanceof Set && value.size > 0) lo[key] = this.mapToObjectRec(Array.from(value)); else lo[key] = value; return lo; } buildValidChunkArray(liveStats, FederationPluginOptions) { if (!FederationPluginOptions.name) return []; const namedChunkRefs = liveStats.compilation.namedChunks.get(FederationPluginOptions.name); if (!namedChunkRefs) return []; const AllReferencedChunksByRemote = namedChunkRefs.getAllReferencedChunks(); const validChunkArray = []; for (const chunk of AllReferencedChunksByRemote)if (chunk.id !== FederationPluginOptions.name) validChunkArray.push(chunk); return validChunkArray; } attach_remote_bundle_name_to_metadata(configurations = [ this.FederationPluginOptions ]) { if (1 !== configurations.length) return; const [configuration] = configurations; if (!configuration?.exposes) return; if (!configuration.bundle_name) return void console.warn(ZeErrors.ERR_MF_CONFIG_MISSING_FILENAME); return { remote_bundle_name: configuration.bundle_name }; } async postDashboardData() {} } export { FederationDashboardPlugin, resolveFederationGraphConfiguration }; //# sourceMappingURL=FederationDashboardPlugin.mjs.map