UNPKG

@module-federation/enhanced

Version:

This package provides enhanced features for module federation.

317 lines (314 loc) • 17.7 kB
'use strict'; Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } }); const require_runtime = require('../../_virtual/_rolldown/runtime.js'); const require_lib_container_options = require('../container/options.js'); const require_utils = require('../../utils.js'); const require_lib_container_runtime_FederationRuntimePlugin = require('../container/runtime/FederationRuntimePlugin.js'); const require_lib_sharing_resolveMatchedConfigs = require('./resolveMatchedConfigs.js'); const require_lib_sharing_utils = require('./utils.js'); const require_lib_sharing_ConsumeSharedFallbackDependency = require('./ConsumeSharedFallbackDependency.js'); const require_lib_sharing_ConsumeSharedModule = require('./ConsumeSharedModule.js'); const require_lib_sharing_ConsumeSharedRuntimeModule = require('./ConsumeSharedRuntimeModule.js'); const require_lib_sharing_ProvideForSharedDependency = require('./ProvideForSharedDependency.js'); const require_lib_sharing_ShareRuntimeModule = require('./ShareRuntimeModule.js'); const require_schemas_sharing_ConsumeSharedPlugin_check = require('../../schemas/sharing/ConsumeSharedPlugin.check.js'); const require_schemas_sharing_ConsumeSharedPlugin = require('../../schemas/sharing/ConsumeSharedPlugin.js'); let _module_federation_sdk = require("@module-federation/sdk"); let _module_federation_sdk_normalize_webpack_path = require("@module-federation/sdk/normalize-webpack-path"); let path = require("path"); path = require_runtime.__toESM(path); //#region src/lib/sharing/ConsumeSharedPlugin.ts const DIRECT_FALLBACK_REGEX = /^(\.\.?(\/|$)|\/|[A-Za-z]:|\\\\)/; const ABSOLUTE_PATH_REGEX = /^(\/|[A-Za-z]:|\\\\)/; const RELATIVE_OR_ABSOLUTE_PATH_REGEX = /^(?:\.{1,2}[\\/]|\/|[A-Za-z]:|\\\\)/; const PACKAGE_NAME_REGEX = /^((?:@[^\\/]+[\\/])?[^\\/]+)/; const { satisfy, parseRange } = require((0, _module_federation_sdk_normalize_webpack_path.normalizeWebpackPath)("webpack/lib/util/semver")); const ModuleNotFoundError = require((0, _module_federation_sdk_normalize_webpack_path.normalizeWebpackPath)("webpack/lib/ModuleNotFoundError")); const { RuntimeGlobals } = require((0, _module_federation_sdk_normalize_webpack_path.normalizeWebpackPath)("webpack")); const LazySet = require((0, _module_federation_sdk_normalize_webpack_path.normalizeWebpackPath)("webpack/lib/util/LazySet")); const WebpackError = require((0, _module_federation_sdk_normalize_webpack_path.normalizeWebpackPath)("webpack/lib/WebpackError")); const validate = require_utils.createSchemaValidation((require_schemas_sharing_ConsumeSharedPlugin_check.init_ConsumeSharedPlugin_check(), require_runtime.__toCommonJS(require_schemas_sharing_ConsumeSharedPlugin_check.ConsumeSharedPlugin_check_exports)).validate, () => (require_schemas_sharing_ConsumeSharedPlugin.init_ConsumeSharedPlugin(), require_runtime.__toCommonJS(require_schemas_sharing_ConsumeSharedPlugin.ConsumeSharedPlugin_exports)).default, { name: "Consume Shared Plugin", baseDataPath: "options" }); const RESOLVE_OPTIONS = { dependencyType: "esm" }; const PLUGIN_NAME = "ConsumeSharedPlugin"; var ConsumeSharedPlugin = class { constructor(options) { if (typeof options !== "string") validate(options); this._consumes = require_lib_container_options.parseOptions(options.consumes, (item, key) => { if (Array.isArray(item)) throw new Error("Unexpected array in options"); return item === key || !(0, _module_federation_sdk.isRequiredVersion)(item) ? { import: key, shareScope: options.shareScope || "default", shareKey: key, requiredVersion: void 0, packageName: void 0, strictVersion: false, singleton: false, eager: false, issuerLayer: void 0, layer: void 0, request: key, include: void 0, exclude: void 0, allowNodeModulesSuffixMatch: void 0, treeShakingMode: void 0 } : { import: key, shareScope: options.shareScope || "default", shareKey: key, requiredVersion: item, strictVersion: true, packageName: void 0, singleton: false, eager: false, issuerLayer: void 0, layer: void 0, request: key, include: void 0, exclude: void 0, allowNodeModulesSuffixMatch: void 0, treeShakingMode: void 0 }; }, (item, key) => { const request = item.request || key; return { import: item.import === false ? void 0 : item.import || request, shareScope: item.shareScope || options.shareScope || "default", shareKey: item.shareKey || request, requiredVersion: item.requiredVersion === false ? false : item.requiredVersion, strictVersion: typeof item.strictVersion === "boolean" ? item.strictVersion : item.import !== false && !item.singleton, packageName: item.packageName, singleton: !!item.singleton, eager: !!item.eager, exclude: item.exclude, include: item.include, issuerLayer: item.issuerLayer ? item.issuerLayer : void 0, layer: item.layer ? item.layer : void 0, request, allowNodeModulesSuffixMatch: item.allowNodeModulesSuffixMatch, treeShakingMode: item.treeShakingMode }; }); } createConsumeSharedModule(compilation, context, request, config) { const requiredVersionWarning = (details) => { const error = new WebpackError(`No required version specified and unable to automatically determine one. ${details}`); error.file = `shared module ${request}`; compilation.warnings.push(error); }; const directFallback = config.import && DIRECT_FALLBACK_REGEX.test(config.import); const resolver = compilation.resolverFactory.get("normal", RESOLVE_OPTIONS); return Promise.all([new Promise((resolve) => { if (!config.import) return resolve(void 0); const resolveContext = { fileDependencies: new LazySet(), contextDependencies: new LazySet(), missingDependencies: new LazySet() }; resolver.resolve({}, directFallback ? compilation.compiler.context : context, config.import, resolveContext, (err, result) => { compilation.contextDependencies.addAll(resolveContext.contextDependencies); compilation.fileDependencies.addAll(resolveContext.fileDependencies); compilation.missingDependencies.addAll(resolveContext.missingDependencies); if (err) { compilation.errors.push(new ModuleNotFoundError(null, err, { name: `resolving fallback for shared module ${request}` })); return resolve(void 0); } resolve(result); }); }), new Promise((resolve) => { if (config.requiredVersion !== void 0) return resolve(config.requiredVersion); let packageName = config.packageName; if (packageName === void 0) { if (ABSOLUTE_PATH_REGEX.test(request)) return resolve(void 0); const match = PACKAGE_NAME_REGEX.exec(request); if (!match) { requiredVersionWarning("Unable to extract the package name from request."); return resolve(void 0); } packageName = match[0]; } require_lib_sharing_utils.getDescriptionFile(compilation.inputFileSystem, context, ["package.json"], (err, result, checkedDescriptionFilePaths) => { if (err) { requiredVersionWarning(`Unable to read description file: ${err}`); return resolve(void 0); } const { data } = result || {}; if (!data) { if (checkedDescriptionFilePaths?.length) requiredVersionWarning([ `Unable to find required version for "${packageName}" in description file/s`, checkedDescriptionFilePaths.join("\n"), "It need to be in dependencies, devDependencies or peerDependencies." ].join("\n")); else requiredVersionWarning(`Unable to find description file in ${context}.`); return resolve(void 0); } if (data["name"] === packageName) return resolve(void 0); resolve(require_lib_sharing_utils.getRequiredVersionFromDescriptionFile(data, packageName)); }, (result) => { if (!result) return false; const { data } = result; const maybeRequiredVersion = require_lib_sharing_utils.getRequiredVersionFromDescriptionFile(data, packageName); return data["name"] === packageName || typeof maybeRequiredVersion === "string"; }); })]).then(([importResolved, requiredVersion]) => { const currentConfig = { ...config, importResolved, import: importResolved ? config.import : void 0, requiredVersion }; const consumedModule = new require_lib_sharing_ConsumeSharedModule.default(directFallback ? compilation.compiler.context : context, currentConfig); if (config.include && typeof config.include.version === "string") { if (!importResolved) return consumedModule; return new Promise((resolveFilter) => { require_lib_sharing_utils.getDescriptionFile(compilation.inputFileSystem, path.default.dirname(importResolved), ["package.json"], (err, result) => { if (err) return resolveFilter(consumedModule); const { data } = result || {}; if (!data || !data["version"] || data["name"] !== request) return resolveFilter(consumedModule); if (config.include && satisfy(parseRange(config.include.version), data["version"])) { if (config.include && config.include.version && config.singleton) require_lib_sharing_utils.addSingletonFilterWarning(compilation, config.shareKey || request, "include", "version", config.include.version, request, importResolved); return resolveFilter(consumedModule); } if (config.include && typeof config.include.fallbackVersion === "string" && config.include.fallbackVersion) { if (satisfy(parseRange(config.include.version), config.include.fallbackVersion)) return resolveFilter(consumedModule); return resolveFilter(void 0); } return resolveFilter(void 0); }); }); } if (config.exclude && typeof config.exclude.version === "string") { if (!importResolved) return consumedModule; if (config.exclude && typeof config.exclude.fallbackVersion === "string" && config.exclude.fallbackVersion) { if (satisfy(parseRange(config.exclude.version), config.exclude.fallbackVersion)) return; return consumedModule; } return new Promise((resolveFilter) => { require_lib_sharing_utils.getDescriptionFile(compilation.inputFileSystem, path.default.dirname(importResolved), ["package.json"], (err, result) => { if (err) return resolveFilter(consumedModule); const { data } = result || {}; if (!data || !data["version"] || data["name"] !== request) return resolveFilter(consumedModule); if (config.exclude && typeof config.exclude.version === "string" && satisfy(parseRange(config.exclude.version), data["version"])) return resolveFilter(void 0); if (config.exclude && config.exclude.version && config.singleton) require_lib_sharing_utils.addSingletonFilterWarning(compilation, config.shareKey || request, "exclude", "version", config.exclude.version, request, importResolved); return resolveFilter(consumedModule); }); }); } return consumedModule; }); } apply(compiler) { new require_lib_container_runtime_FederationRuntimePlugin.default().apply(compiler); process.env["FEDERATION_WEBPACK_PATH"] = process.env["FEDERATION_WEBPACK_PATH"] || (0, _module_federation_sdk_normalize_webpack_path.getWebpackPath)(compiler); compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation, { normalModuleFactory }) => { compilation.dependencyFactories.set(require_lib_sharing_ConsumeSharedFallbackDependency.default, normalModuleFactory); let unresolvedConsumes, resolvedConsumes, prefixedConsumes; const promise = require_lib_sharing_resolveMatchedConfigs.resolveMatchedConfigs(compilation, this._consumes).then(({ resolved, unresolved, prefixed }) => { resolvedConsumes = resolved; unresolvedConsumes = unresolved; prefixedConsumes = prefixed; }); normalModuleFactory.hooks.factorize.tapPromise(PLUGIN_NAME, async (resolveData) => { const { context, request, dependencies, contextInfo } = resolveData; const boundCreateConsumeSharedModule = this.createConsumeSharedModule.bind(this); return promise.then(() => { if (dependencies[0] instanceof require_lib_sharing_ConsumeSharedFallbackDependency.default || dependencies[0] instanceof require_lib_sharing_ProvideForSharedDependency.default) return; const { context, request, contextInfo } = resolveData; const match = unresolvedConsumes.get(require_lib_sharing_utils.createLookupKeyForSharing(request, contextInfo.issuerLayer)) || unresolvedConsumes.get(require_lib_sharing_utils.createLookupKeyForSharing(request, void 0)); if (match !== void 0) return boundCreateConsumeSharedModule(compilation, context, request, match); let reconstructed = null; let modulePathAfterNodeModules = null; if (request && !path.default.isAbsolute(request) && RELATIVE_OR_ABSOLUTE_PATH_REGEX.test(request)) { reconstructed = path.default.join(context, request); modulePathAfterNodeModules = require_lib_sharing_utils.extractPathAfterNodeModules(reconstructed); if (modulePathAfterNodeModules) { const moduleMatch = unresolvedConsumes.get(require_lib_sharing_utils.createLookupKeyForSharing(modulePathAfterNodeModules, contextInfo.issuerLayer)) || unresolvedConsumes.get(require_lib_sharing_utils.createLookupKeyForSharing(modulePathAfterNodeModules, void 0)); if (moduleMatch !== void 0 && moduleMatch.allowNodeModulesSuffixMatch) return boundCreateConsumeSharedModule(compilation, context, modulePathAfterNodeModules, moduleMatch); } const reconstructedMatch = unresolvedConsumes.get(require_lib_sharing_utils.createLookupKeyForSharing(reconstructed, contextInfo.issuerLayer)) || unresolvedConsumes.get(require_lib_sharing_utils.createLookupKeyForSharing(reconstructed, void 0)); if (reconstructedMatch !== void 0) return boundCreateConsumeSharedModule(compilation, context, reconstructed, reconstructedMatch); } for (const [prefix, options] of prefixedConsumes) { const lookup = options.request || prefix; if (options.issuerLayer) { if (!contextInfo.issuerLayer) continue; if (contextInfo.issuerLayer !== options.issuerLayer) continue; } if (request.startsWith(lookup)) { const remainder = request.slice(lookup.length); if (!require_lib_sharing_utils.testRequestFilters(remainder, options.include?.request, options.exclude?.request)) continue; return boundCreateConsumeSharedModule(compilation, context, request, { ...options, import: options.import ? options.import + remainder : void 0, shareKey: options.shareKey + remainder, layer: options.layer }); } } if (modulePathAfterNodeModules) for (const [prefix, options] of prefixedConsumes) { if (!options.allowNodeModulesSuffixMatch) continue; if (options.issuerLayer) { if (!contextInfo.issuerLayer) continue; if (contextInfo.issuerLayer !== options.issuerLayer) continue; } const lookup = options.request || prefix; if (modulePathAfterNodeModules.startsWith(lookup)) { const remainder = modulePathAfterNodeModules.slice(lookup.length); if (!require_lib_sharing_utils.testRequestFilters(remainder, options.include?.request, options.exclude?.request)) continue; return boundCreateConsumeSharedModule(compilation, context, modulePathAfterNodeModules, { ...options, import: options.import ? options.import + remainder : void 0, shareKey: options.shareKey + remainder, layer: options.layer }); } } }); }); normalModuleFactory.hooks.createModule.tapPromise(PLUGIN_NAME, ({ resource }, { context, dependencies }) => { const boundCreateConsumeSharedModule = this.createConsumeSharedModule.bind(this); if (dependencies[0] instanceof require_lib_sharing_ConsumeSharedFallbackDependency.default || dependencies[0] instanceof require_lib_sharing_ProvideForSharedDependency.default) return Promise.resolve(); if (resource) { const options = resolvedConsumes.get(resource); if (options !== void 0) return boundCreateConsumeSharedModule(compilation, context, resource, options); } return Promise.resolve(); }); compilation.hooks.finishModules.tapAsync({ name: PLUGIN_NAME, stage: 10 }, (modules, callback) => { for (const module of modules) { if (!(module instanceof require_lib_sharing_ConsumeSharedModule.default) || !module.options.import) continue; let dependency; if (module.options.eager) dependency = module.dependencies[0]; else dependency = module.blocks[0]?.dependencies[0]; if (dependency) { const fallbackModule = compilation.moduleGraph.getModule(dependency); if (fallbackModule && fallbackModule.buildMeta && fallbackModule.buildInfo) { module.buildMeta = { ...fallbackModule.buildMeta }; module.buildInfo = { ...fallbackModule.buildInfo }; compilation.moduleGraph.getExportsInfo(module).setUnknownExportsProvided(); } } } callback(); }); compilation.hooks.additionalTreeRuntimeRequirements.tap(PLUGIN_NAME, (chunk, set) => { set.add(RuntimeGlobals.module); set.add(RuntimeGlobals.moduleCache); set.add(RuntimeGlobals.moduleFactoriesAddOnly); set.add(RuntimeGlobals.shareScopeMap); set.add(RuntimeGlobals.initializeSharing); set.add(RuntimeGlobals.hasOwnProperty); compilation.addRuntimeModule(chunk, new require_lib_sharing_ConsumeSharedRuntimeModule.default(set)); compilation.addRuntimeModule(chunk, new require_lib_sharing_ShareRuntimeModule.default()); }); }); } }; //#endregion exports.default = ConsumeSharedPlugin; //# sourceMappingURL=ConsumeSharedPlugin.js.map