@module-federation/enhanced
Advanced tools
Comparing version 0.0.0-next-20231220085130 to 0.0.0-next-20231221061836
{ | ||
"name": "@module-federation/enhanced", | ||
"version": "0.0.3", | ||
"version": "0.0.4", | ||
"type": "commonjs", | ||
@@ -31,4 +31,6 @@ "main": "./src/index.js", | ||
"dependencies": { | ||
"@module-federation/sdk": "workspace:*" | ||
"@module-federation/sdk": "workspace:*", | ||
"@module-federation/runtime": "workspace:*", | ||
"@module-federation/webpack-bundler-runtime": "workspace:*" | ||
} | ||
} |
@@ -54,5 +54,6 @@ "use strict"; | ||
const entryOptions = upperContext.chunk.getEntryOptions(); | ||
const initialChunks = Array.from(upperContext.chunk.getAllInitialChunks()).map((chunk) => chunk.id); | ||
const chunksToRef = entryOptions?.dependOn | ||
? [...entryOptions.dependOn, upperContext.chunk.id] | ||
: [upperContext.chunk.id]; | ||
? [...entryOptions.dependOn, ...initialChunks] | ||
: [...initialChunks]; | ||
remotes = this._getRemotes(compiler.webpack.RuntimeGlobals, requirements, Boolean(hasRemoteModules), chunksToRef, remotes); | ||
@@ -59,0 +60,0 @@ shared = this._getShared(compiler.webpack.RuntimeGlobals, requirements, Boolean(consumeShares), chunksToRef, shared); |
@@ -7,2 +7,3 @@ import { ExposeOptions } from './ContainerEntryModule'; | ||
shareScope: string; | ||
runtimePlugins: string[]; | ||
/** | ||
@@ -12,4 +13,5 @@ * @param {string} name entry name | ||
* @param {string} shareScope name of the share scope | ||
* @param {string[]} runtimePlugins Runtime plugin file paths or package name. | ||
*/ | ||
constructor(name: string, exposes: [string, ExposeOptions][], shareScope: string); | ||
constructor(name: string, exposes: [string, ExposeOptions][], shareScope: string, runtimePlugins: string[]); | ||
/** | ||
@@ -16,0 +18,0 @@ * @returns {string | null} an identifier to merge equal requests |
@@ -15,4 +15,5 @@ "use strict"; | ||
* @param {string} shareScope name of the share scope | ||
* @param {string[]} runtimePlugins Runtime plugin file paths or package name. | ||
*/ | ||
constructor(name, exposes, shareScope) { | ||
constructor(name, exposes, shareScope, runtimePlugins) { | ||
super(); | ||
@@ -22,2 +23,3 @@ this.name = name; | ||
this.shareScope = shareScope; | ||
this.runtimePlugins = runtimePlugins; | ||
} | ||
@@ -24,0 +26,0 @@ /** |
import type { Compilation } from 'webpack'; | ||
declare const Module: typeof import("webpack").Module; | ||
import type { LibIdentOptions, NeedBuildContext, RequestShortener, ObjectDeserializerContext, ObjectSerializerContext, WebpackOptions, InputFileSystem, ResolverWithOptions } from 'webpack/lib/Module'; | ||
import type WebpackError from 'webpack/lib/WebpackError'; | ||
declare const Module: typeof import("webpack").Module; | ||
export type ExposeOptions = { | ||
@@ -19,2 +19,3 @@ /** | ||
private _shareScope; | ||
private _runtimePlugins; | ||
/** | ||
@@ -25,3 +26,3 @@ * @param {string} name container entry name | ||
*/ | ||
constructor(name: string, exposes: [string, ExposeOptions][], shareScope: string); | ||
constructor(name: string, exposes: [string, ExposeOptions][], shareScope: string, runtimePlugins: string[]); | ||
/** | ||
@@ -75,3 +76,3 @@ * @param {ObjectDeserializerContext} context context | ||
sources: Map<any, any>; | ||
runtimeRequirements: Set<"__webpack_require__.o" | "__webpack_require__.d" | "__webpack_exports__">; | ||
runtimeRequirements: Set<"__webpack_exports__" | "__webpack_require__.d" | "__webpack_require__.o">; | ||
}; | ||
@@ -78,0 +79,0 @@ /** |
@@ -11,8 +11,11 @@ /* | ||
const normalize_webpack_path_1 = require("@module-federation/sdk/normalize-webpack-path"); | ||
const ContainerExposedDependency_1 = __importDefault(require("./ContainerExposedDependency")); | ||
const FederationRuntimePlugin_1 = __importDefault(require("./runtime/FederationRuntimePlugin")); | ||
const utils_1 = require("./runtime/utils"); | ||
const Constants_1 = require("../Constants"); | ||
const makeSerializable = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack/lib/util/makeSerializable')); | ||
const { sources: webpackSources } = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack')); | ||
const { AsyncDependenciesBlock, Template, Module, RuntimeGlobals } = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack')); | ||
const { JAVASCRIPT_MODULE_TYPE_DYNAMIC } = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack/lib/ModuleTypeConstants')); | ||
const StaticExportsDependency = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack/lib/dependencies/StaticExportsDependency')); | ||
const ContainerExposedDependency_1 = __importDefault(require("./ContainerExposedDependency")); | ||
const EntryDependency = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack/lib/dependencies/EntryDependency')); | ||
const SOURCE_TYPES = new Set(['javascript']); | ||
@@ -25,7 +28,8 @@ class ContainerEntryModule extends Module { | ||
*/ | ||
constructor(name, exposes, shareScope) { | ||
super(JAVASCRIPT_MODULE_TYPE_DYNAMIC, null); | ||
constructor(name, exposes, shareScope, runtimePlugins) { | ||
super(Constants_1.JAVASCRIPT_MODULE_TYPE_DYNAMIC, null); | ||
this._name = name; | ||
this._exposes = exposes; | ||
this._shareScope = shareScope; | ||
this._runtimePlugins = runtimePlugins; | ||
} | ||
@@ -38,3 +42,3 @@ /** | ||
const { read } = context; | ||
const obj = new ContainerEntryModule(read(), read(), read()); | ||
const obj = new ContainerEntryModule(read(), read(), read(), read()); | ||
//@ts-ignore | ||
@@ -119,2 +123,5 @@ obj.deserialize(context); | ||
new StaticExportsDependency(['get', 'init'], false)); | ||
this.addDependency( | ||
// @ts-ignore | ||
new EntryDependency(FederationRuntimePlugin_1.default.getFilePath(this._name, this._runtimePlugins))); | ||
callback(); | ||
@@ -170,2 +177,12 @@ } | ||
} | ||
const initRuntimeDep = this.dependencies[1]; | ||
const initRuntimeModuleGetter = runtimeTemplate.moduleRaw({ | ||
module: moduleGraph.getModule(initRuntimeDep), | ||
chunkGraph, | ||
// @ts-expect-error | ||
request: initRuntimeDep.userRequest, | ||
weak: false, | ||
runtimeRequirements, | ||
}); | ||
const federationGlobal = (0, utils_1.getFederationGlobalScope)(RuntimeGlobals || {}); | ||
const source = Template.asString([ | ||
@@ -191,9 +208,11 @@ `var moduleMap = {`, | ||
`var init = ${runtimeTemplate.basicFunction('shareScope, initScope', [ | ||
`if (!${RuntimeGlobals.shareScopeMap}) return;`, | ||
`var name = ${JSON.stringify(this._shareScope)}`, | ||
`var oldScope = ${RuntimeGlobals.shareScopeMap}[name];`, | ||
`if(oldScope && oldScope !== shareScope) throw new Error("Container initialization failed as it has already been initialized with a different share scope");`, | ||
`${RuntimeGlobals.shareScopeMap}[name] = shareScope;`, | ||
`return ${RuntimeGlobals.initializeSharing}(name, initScope);`, | ||
`return ${federationGlobal}.bundlerRuntime.initContainerEntry({${Template.indent([ | ||
`webpackRequire: ${RuntimeGlobals.require},`, | ||
`shareScope: shareScope,`, | ||
`initScope: initScope,`, | ||
`shareScopeKey: ${JSON.stringify(this._shareScope)}`, | ||
])}`, | ||
'})', | ||
])};`, | ||
`${initRuntimeModuleGetter}`, | ||
'', | ||
@@ -231,2 +250,3 @@ '// This exports getters to disallow modifications', | ||
write(this._shareScope); | ||
write(this._runtimePlugins); | ||
super.serialize(context); | ||
@@ -233,0 +253,0 @@ } |
@@ -24,4 +24,4 @@ /* | ||
callback(null, { | ||
//@ts-ignore | ||
module: new ContainerEntryModule_1.default(dep.name, dep.exposes, dep.shareScope), | ||
// @ts-ignore | ||
module: new ContainerEntryModule_1.default(dep.name, dep.exposes, dep.shareScope, dep.runtimePlugins), | ||
}); | ||
@@ -28,0 +28,0 @@ } |
@@ -5,2 +5,3 @@ import type { Compiler } from 'webpack'; | ||
_options: ContainerPluginOptions; | ||
name: string; | ||
/** | ||
@@ -10,4 +11,5 @@ * @param {ContainerPluginOptions} options options | ||
constructor(options: ContainerPluginOptions); | ||
static patchChunkSplit(compiler: Compiler, name: string): void; | ||
apply(compiler: Compiler): void; | ||
} | ||
export default ContainerPlugin; |
@@ -15,6 +15,7 @@ "use strict"; | ||
const options_1 = require("./options"); | ||
const FederationRuntimePlugin_1 = __importDefault(require("./runtime/FederationRuntimePlugin")); | ||
const ContainerPlugin_check_1 = __importDefault(require("../../schemas/container/ContainerPlugin.check")); | ||
const ContainerPlugin_1 = __importDefault(require("../../schemas/container/ContainerPlugin")); | ||
const createSchemaValidation = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack/lib/util/create-schema-validation')); | ||
const validate = createSchemaValidation( | ||
//eslint-disable-next-line | ||
require('webpack/schemas/plugins/container/ContainerPlugin.check.js'), () => require('webpack/schemas/plugins/container/ContainerPlugin.json'), { | ||
const validate = createSchemaValidation(ContainerPlugin_check_1.default, () => ContainerPlugin_1.default, { | ||
name: 'Container Plugin', | ||
@@ -30,2 +31,3 @@ baseDataPath: 'options', | ||
validate(options); | ||
this.name = PLUGIN_NAME; | ||
this._options = { | ||
@@ -48,8 +50,83 @@ name: options.name, | ||
})), | ||
runtimePlugins: options.runtimePlugins, | ||
}; | ||
} | ||
// container should not be affected by splitChunks | ||
static patchChunkSplit(compiler, name) { | ||
const { splitChunks } = compiler.options.optimization; | ||
const patchChunkSplit = (cacheGroup) => { | ||
switch (typeof cacheGroup) { | ||
case 'boolean': | ||
case 'string': | ||
case 'function': | ||
break; | ||
// cacheGroup.chunks 会继承 splitChunks.chunks ,因此只需要对单独设置了 chunks 的 做修改 | ||
case 'object': | ||
{ | ||
if (cacheGroup instanceof RegExp) { | ||
break; | ||
} | ||
if (!cacheGroup.chunks) { | ||
break; | ||
} | ||
if (typeof cacheGroup.chunks === 'function') { | ||
const prevChunks = cacheGroup.chunks; | ||
cacheGroup.chunks = (chunk) => { | ||
if (chunk.name && chunk.name === name) { | ||
return false; | ||
} | ||
return prevChunks(chunk); | ||
}; | ||
break; | ||
} | ||
if (cacheGroup.chunks === 'all') { | ||
cacheGroup.chunks = (chunk) => { | ||
if (chunk.name && chunk.name === name) { | ||
return false; | ||
} | ||
return true; | ||
}; | ||
break; | ||
} | ||
if (cacheGroup.chunks === 'initial') { | ||
cacheGroup.chunks = (chunk) => { | ||
if (chunk.name && chunk.name === name) { | ||
return false; | ||
} | ||
return chunk.isOnlyInitial(); | ||
}; | ||
break; | ||
} | ||
} | ||
break; | ||
} | ||
}; | ||
if (!splitChunks) { | ||
return; | ||
} | ||
// 修改 splitChunk.chunks | ||
patchChunkSplit(splitChunks); | ||
const cacheGroups = splitChunks.cacheGroups; | ||
if (!cacheGroups) { | ||
return; | ||
} | ||
// 修改 splitChunk.cacheGroups[key].chunks | ||
Object.keys(cacheGroups).forEach((cacheGroupKey) => { | ||
patchChunkSplit(cacheGroups[cacheGroupKey]); | ||
}); | ||
} | ||
apply(compiler) { | ||
process.env['FEDERATION_WEBPACK_PATH'] = | ||
process.env['FEDERATION_WEBPACK_PATH'] || (0, normalize_webpack_path_1.getWebpackPath)(compiler); | ||
const { name, exposes, shareScope, filename, library, runtime } = this._options; | ||
const useModuleFederationPlugin = compiler.options.plugins.find((p) => { | ||
if (typeof p !== 'object' || !p) { | ||
return false; | ||
} | ||
return p['name'] === 'ModuleFederationPlugin'; | ||
}); | ||
if (!useModuleFederationPlugin) { | ||
ContainerPlugin.patchChunkSplit(compiler, this._options.name); | ||
} | ||
new FederationRuntimePlugin_1.default().apply(compiler); | ||
const { name, exposes, shareScope, filename, library, runtime, runtimePlugins, } = this._options; | ||
if (library && | ||
@@ -62,4 +139,6 @@ compiler.options.output && | ||
compiler.hooks.make.tapAsync(PLUGIN_NAME, (compilation, callback) => { | ||
const dep = new ContainerEntryDependency_1.default(name, | ||
//@ts-ignore | ||
const dep = new ContainerEntryDependency_1.default(name, exposes, shareScope); | ||
exposes, shareScope, runtimePlugins); | ||
const hasSingleRuntimeChunk = compilation.options?.optimization?.runtimeChunk; | ||
dep.loc = { name }; | ||
@@ -71,10 +150,30 @@ compilation.addEntry(compilation.options.context || '', | ||
filename, | ||
runtime, | ||
runtime: hasSingleRuntimeChunk ? false : runtime, | ||
library, | ||
}, (error) => { | ||
if (error) { | ||
if (error) | ||
return callback(error); | ||
if (hasSingleRuntimeChunk) { | ||
// Add to single runtime chunk as well. | ||
// Allows for singleton runtime graph with all needed runtime modules for federation | ||
addEntryToSingleRuntimeChunk(); | ||
} | ||
callback(); | ||
else { | ||
callback(); | ||
} | ||
}); | ||
// Function to add entry for undefined runtime | ||
const addEntryToSingleRuntimeChunk = () => { | ||
compilation.addEntry(compilation.options.context || '', | ||
//@ts-ignore | ||
dep, { | ||
name: name ? name + '_partial' : undefined, // give unique name name | ||
runtime: undefined, | ||
library, | ||
}, (error) => { | ||
if (error) | ||
return callback(error); | ||
callback(); | ||
}); | ||
}; | ||
}); | ||
@@ -85,3 +184,5 @@ compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation, { normalModuleFactory }) => { | ||
new ContainerEntryModuleFactory_1.default()); | ||
compilation.dependencyFactories.set(ContainerExposedDependency_1.default, normalModuleFactory); | ||
compilation.dependencyFactories.set( | ||
//@ts-ignore | ||
ContainerExposedDependency_1.default, normalModuleFactory); | ||
}); | ||
@@ -88,0 +189,0 @@ } |
@@ -15,2 +15,5 @@ "use strict"; | ||
const options_1 = require("./options"); | ||
const FederationRuntimePlugin_1 = __importDefault(require("./runtime/FederationRuntimePlugin")); | ||
const ContainerReferencePlugin_1 = __importDefault(require("../../schemas/container/ContainerReferencePlugin")); | ||
const ContainerReferencePlugin_check_1 = __importDefault(require("../../schemas/container/ContainerReferencePlugin.check")); | ||
const { ExternalsPlugin } = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack')); | ||
@@ -20,3 +23,3 @@ const createSchemaValidation = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack/lib/util/create-schema-validation')); | ||
//eslint-disable-next-line | ||
require('webpack/schemas/plugins/container/ContainerReferencePlugin.check.js'), () => require('webpack/schemas/plugins/container/ContainerReferencePlugin.json'), { | ||
ContainerReferencePlugin_check_1.default, () => ContainerReferencePlugin_1.default, { | ||
name: 'Container Reference Plugin', | ||
@@ -49,2 +52,4 @@ baseDataPath: 'options', | ||
const { _remotes: remotes, _remoteType: remoteType } = this; | ||
// @ts-ignore | ||
new FederationRuntimePlugin_1.default().apply(compiler); | ||
/** @type {Record<string, string>} */ | ||
@@ -51,0 +56,0 @@ const remoteExternals = {}; |
@@ -5,3 +5,3 @@ import type { ChunkGraph, Chunk } from 'webpack'; | ||
declare class FallbackModule extends Module { | ||
private requests; | ||
requests: string[]; | ||
private _identifier; | ||
@@ -8,0 +8,0 @@ /** |
@@ -12,6 +12,6 @@ /* | ||
const FallbackItemDependency_1 = __importDefault(require("./FallbackItemDependency")); | ||
const Constants_1 = require("../Constants"); | ||
const { sources: webpackSources } = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack')); | ||
const { Template, Module, RuntimeGlobals } = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack')); | ||
const makeSerializable = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack/lib/util/makeSerializable')); | ||
const { WEBPACK_MODULE_TYPE_FALLBACK } = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack/lib/ModuleTypeConstants')); | ||
const TYPES = new Set(['javascript']); | ||
@@ -24,3 +24,3 @@ const RUNTIME_REQUIREMENTS = new Set([RuntimeGlobals.module]); | ||
constructor(requests) { | ||
super(WEBPACK_MODULE_TYPE_FALLBACK); | ||
super(Constants_1.WEBPACK_MODULE_TYPE_FALLBACK); | ||
this.requests = requests; | ||
@@ -27,0 +27,0 @@ this._identifier = `fallback ${this.requests.join(' ')}`; |
@@ -7,8 +7,7 @@ import type { Compiler, WebpackPluginInstance } from 'webpack'; | ||
export declare class HoistContainerReferences implements WebpackPluginInstance { | ||
/** | ||
* @function apply | ||
* @param {Compiler} compiler The webpack compiler object | ||
*/ | ||
apply(compiler: Compiler): void; | ||
private chunkContainsContainerEntryModule; | ||
private hoistModulesInChunk; | ||
private getRuntimeChunks; | ||
} | ||
export default HoistContainerReferences; |
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.HoistContainerReferences = void 0; | ||
const ContainerEntryModule_1 = __importDefault(require("./ContainerEntryModule")); | ||
/** | ||
@@ -9,60 +13,39 @@ * This class is used to hoist container references in the code. | ||
class HoistContainerReferences { | ||
/** | ||
* @function apply | ||
* @param {Compiler} compiler The webpack compiler object | ||
*/ | ||
apply(compiler) { | ||
// Hook into the compilation process | ||
compiler.hooks.thisCompilation.tap('HoistContainerReferences', (compilation) => { | ||
// After chunks are optimized, perform the hoisting | ||
compilation.hooks.afterOptimizeChunks.tap('HoistContainerReferences', (chunks, chunkGroups) => { | ||
// Create a map to store chunks by their id or name | ||
/** @type {Map<(string|number), Chunk>} */ | ||
const chunkSet = new Map(); | ||
// Create a set to store external module requests | ||
/** @type {Set<Module>} */ | ||
const externalRequests = new Set(); | ||
// Populate the chunkSet with chunks | ||
compilation.hooks.afterOptimizeChunks.tap('HoistContainerReferences', (chunks) => { | ||
for (const chunk of chunks) { | ||
const ident = chunk.id || chunk.name; | ||
if (ident) { | ||
chunkSet.set(ident, chunk); | ||
if (this.chunkContainsContainerEntryModule(chunk, compilation)) { | ||
this.hoistModulesInChunk(chunk, compilation); | ||
} | ||
} | ||
// Iterate over chunks again to handle remote modules | ||
for (const chunk of chunks) { | ||
// Get iterable of remote modules for the chunk | ||
const remoteModules = compilation.chunkGraph.getChunkModulesIterableBySourceType(chunk, 'remote'); | ||
if (!remoteModules) | ||
continue; | ||
// Iterate over remote modules | ||
for (const remoteModule of remoteModules) { | ||
// Iterate over dependencies of the remote module | ||
for (const dep of remoteModule.dependencies) { | ||
// Get the module associated with the dependency | ||
const mod = compilation.moduleGraph.getModule(dep); | ||
// If the module exists and the chunk has a runtime, add the module to externalRequests | ||
if (mod !== null && chunk.runtime) { | ||
externalRequests.add(mod); | ||
// Get the runtime chunk(s) associated with the chunk | ||
const runtimeChunk = typeof chunk.runtime === 'string' || | ||
typeof chunk.runtime === 'number' | ||
? [chunk.runtime] | ||
: [...chunk.runtime]; | ||
// Iterate over runtime chunks | ||
for (const runtimeChunkId of runtimeChunk) { | ||
// Get the runtime chunk from the chunkSet | ||
const runtimeChunk = chunkSet.get(runtimeChunkId); | ||
// If the runtime chunk exists, connect it with the module in the chunk graph | ||
if (runtimeChunk) { | ||
compilation.chunkGraph.connectChunkAndModule(runtimeChunk, mod); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
}); | ||
}); | ||
} | ||
chunkContainsContainerEntryModule(chunk, compilation) { | ||
for (const module of compilation.chunkGraph.getChunkModulesIterable(chunk)) { | ||
if (module instanceof ContainerEntryModule_1.default) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
hoistModulesInChunk(chunk, compilation) { | ||
const chunkGraph = compilation.chunkGraph; | ||
const runtimeChunks = this.getRuntimeChunks(chunk, compilation); | ||
for (const module of chunkGraph.getChunkModulesIterable(chunk)) { | ||
for (const runtimeChunk of runtimeChunks) { | ||
chunkGraph.connectChunkAndModule(runtimeChunk, module); | ||
} | ||
} | ||
} | ||
getRuntimeChunks(chunk, compilation) { | ||
const runtimeChunks = []; | ||
for (const c of compilation.chunks) { | ||
if (c.hasRuntime() && c !== chunk) { | ||
runtimeChunks.push(c); | ||
} | ||
} | ||
return runtimeChunks; | ||
} | ||
} | ||
@@ -69,0 +52,0 @@ exports.HoistContainerReferences = HoistContainerReferences; |
@@ -5,2 +5,3 @@ import type { Compiler } from 'webpack'; | ||
private _options; | ||
name: string; | ||
/** | ||
@@ -7,0 +8,0 @@ * @param {ModuleFederationPluginOptions} options options |
@@ -15,11 +15,13 @@ /* | ||
const ContainerReferencePlugin_1 = __importDefault(require("./ContainerReferencePlugin")); | ||
const ModuleFederationPlugin_check_js_1 = __importDefault(require("webpack/schemas/plugins/container/ModuleFederationPlugin.check.js")); | ||
const ModuleFederationPlugin_check_1 = __importDefault(require("../../schemas/container/ModuleFederationPlugin.check")); | ||
const ModuleFederationPlugin_1 = __importDefault(require("../../schemas/container/ModuleFederationPlugin")); | ||
const FederationRuntimePlugin_1 = __importDefault(require("./runtime/FederationRuntimePlugin")); | ||
const createSchemaValidation = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack/lib/util/create-schema-validation')); | ||
const validate = createSchemaValidation( | ||
//eslint-disable-next-line | ||
ModuleFederationPlugin_check_js_1.default, () => ModuleFederationPlugin_1.default, { | ||
ModuleFederationPlugin_check_1.default, () => ModuleFederationPlugin_1.default, { | ||
name: 'Module Federation Plugin', | ||
baseDataPath: 'options', | ||
}); | ||
const PLUGIN_NAME = 'ModuleFederationPlugin'; | ||
class ModuleFederationPlugin { | ||
@@ -31,2 +33,3 @@ /** | ||
validate(options); | ||
this.name = PLUGIN_NAME; | ||
this._options = options; | ||
@@ -43,2 +46,4 @@ } | ||
const { _options: options } = this; | ||
// @ts-ignore | ||
new FederationRuntimePlugin_1.default(options).apply(compiler); | ||
const library = options.library || { type: 'var', name: options.name }; | ||
@@ -49,2 +54,10 @@ const remoteType = options.remoteType || | ||
: 'script'); | ||
const useContainerPlugin = options.exposes && | ||
(Array.isArray(options.exposes) | ||
? options.exposes.length > 0 | ||
: Object.keys(options.exposes).length > 0); | ||
if (useContainerPlugin) { | ||
// @ts-ignore | ||
ContainerPlugin_1.default.patchChunkSplit(compiler, this._options.name); | ||
} | ||
if (library && | ||
@@ -55,6 +68,3 @@ !compiler.options.output.enabledLibraryTypes?.includes(library.type)) { | ||
compiler.hooks.afterPlugins.tap('ModuleFederationPlugin', () => { | ||
if (options.exposes && | ||
(Array.isArray(options.exposes) | ||
? options.exposes.length > 0 | ||
: Object.keys(options.exposes).length > 0)) { | ||
if (useContainerPlugin) { | ||
new ContainerPlugin_1.default({ | ||
@@ -67,3 +77,6 @@ //@ts-ignore | ||
shareScope: options.shareScope, | ||
//@ts-ignore | ||
exposes: options.exposes, | ||
runtimePlugins: options.runtimePlugins, | ||
//@ts-ignore | ||
}).apply(compiler); | ||
@@ -70,0 +83,0 @@ } |
@@ -13,5 +13,5 @@ "use strict"; | ||
const RemoteToExternalDependency_1 = __importDefault(require("./RemoteToExternalDependency")); | ||
const Constants_1 = require("../Constants"); | ||
const { sources: webpackSources } = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack')); | ||
const { Module, RuntimeGlobals } = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack')); | ||
const { WEBPACK_MODULE_TYPE_REMOTE } = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack/lib/ModuleTypeConstants')); | ||
const makeSerializable = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack/lib/util/makeSerializable')); | ||
@@ -28,3 +28,3 @@ const TYPES = new Set(['remote', 'share-init']); | ||
constructor(request, externalRequests, internalRequest, shareScope) { | ||
super(WEBPACK_MODULE_TYPE_REMOTE); | ||
super(Constants_1.WEBPACK_MODULE_TYPE_REMOTE); | ||
this.request = request; | ||
@@ -31,0 +31,0 @@ this.externalRequests = externalRequests; |
@@ -8,2 +8,3 @@ "use strict"; | ||
const normalize_webpack_path_1 = require("@module-federation/sdk/normalize-webpack-path"); | ||
const utils_1 = require("./runtime/utils"); | ||
const { Template, RuntimeModule, RuntimeGlobals } = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack')); | ||
@@ -22,2 +23,3 @@ class RemoteRuntimeModule extends RuntimeModule { | ||
const idToExternalAndNameMapping = {}; | ||
const idToRemoteMap = {}; | ||
const allChunks = [ | ||
@@ -40,5 +42,7 @@ ...Array.from(this.chunk?.getAllReferencedChunks() || []), | ||
const dep = module.dependencies[0]; | ||
// @ts-ignore | ||
const externalModule = moduleGraph.getModule(dep); | ||
const externalModuleId = chunkGraph && externalModule | ||
? chunkGraph.getModuleId(externalModule) | ||
? // @ts-ignore | ||
chunkGraph.getModuleId(externalModule) | ||
: undefined; | ||
@@ -49,54 +53,102 @@ if (id !== undefined) { | ||
idToExternalAndNameMapping[id] = [shareScope, name, externalModuleId]; | ||
const remoteModules = []; | ||
// FallbackModule has requests | ||
if ('requests' in externalModule && externalModule.requests) { | ||
externalModule.dependencies.forEach((dependency) => { | ||
const remoteModule = moduleGraph.getModule(dependency); | ||
if (remoteModule) { | ||
// @ts-ignore | ||
remoteModules.push(remoteModule); | ||
} | ||
}); | ||
} | ||
else { | ||
remoteModules.push(externalModule); | ||
} | ||
idToRemoteMap[id] = []; | ||
remoteModules.forEach((remoteModule) => { | ||
const externalModuleId = chunkGraph && | ||
remoteModule && | ||
// @ts-ignore | ||
chunkGraph.getModuleId(remoteModule); | ||
idToRemoteMap[id].push({ | ||
externalType: remoteModule.externalType, | ||
request: remoteModule.request, | ||
externalModuleId, | ||
}); | ||
}); | ||
} | ||
} | ||
} | ||
const federationGlobal = (0, utils_1.getFederationGlobalScope)(RuntimeGlobals || {}); | ||
return Template.asString([ | ||
`var chunkMapping = ${JSON.stringify(chunkToRemotesMapping, null, '\t')};`, | ||
`var idToExternalAndNameMapping = ${JSON.stringify(idToExternalAndNameMapping, null, '\t')};`, | ||
`var idToRemoteMap = ${JSON.stringify(idToRemoteMap, null, '\t')};`, | ||
`${federationGlobal}.bundlerRuntimeOptions.remotes = {idToRemoteMap,chunkMapping, idToExternalAndNameMapping, webpackRequire:${RuntimeGlobals.require}};`, | ||
`${RuntimeGlobals.ensureChunkHandlers}.remotes = ${runtimeTemplate.basicFunction('chunkId, promises', [ | ||
`if(${RuntimeGlobals.hasOwnProperty}(chunkMapping, chunkId)) {`, | ||
Template.indent([ | ||
`chunkMapping[chunkId].forEach(${runtimeTemplate.basicFunction('id', [ | ||
`var getScope = ${RuntimeGlobals.currentRemoteGetScope};`, | ||
'if(!getScope) getScope = [];', | ||
'var data = idToExternalAndNameMapping[id];', | ||
'if(getScope.indexOf(data) >= 0) return;', | ||
'getScope.push(data);', | ||
`if(data.p) return promises.push(data.p);`, | ||
`var onError = ${runtimeTemplate.basicFunction('error', [ | ||
'if(!error) error = new Error("Container missing");', | ||
'if(typeof error.message === "string")', | ||
Template.indent(`error.message += '\\nwhile loading "' + data[1] + '" from ' + data[2];`), | ||
`${RuntimeGlobals.moduleFactories}[id] = ${runtimeTemplate.basicFunction('', ['throw error;'])}`, | ||
'data.p = 0;', | ||
])};`, | ||
`var handleFunction = ${runtimeTemplate.basicFunction('fn, arg1, arg2, d, next, first', [ | ||
'try {', | ||
Template.indent([ | ||
'var promise = fn(arg1, arg2);', | ||
'if(promise && promise.then) {', | ||
Template.indent([ | ||
`var p = promise.then(${runtimeTemplate.returningFunction('next(result, d)', 'result')}, onError);`, | ||
`if(first) promises.push(data.p = p); else return p;`, | ||
]), | ||
'} else {', | ||
Template.indent(['return next(promise, d, first);']), | ||
'}', | ||
]), | ||
'} catch(error) {', | ||
Template.indent(['onError(error);']), | ||
'}', | ||
])}`, | ||
`var onExternal = ${runtimeTemplate.returningFunction(`external ? handleFunction(${RuntimeGlobals.initializeSharing}, data[0], 0, external, onInitialized, first) : onError()`, 'external, _, first')};`, | ||
`var onInitialized = ${runtimeTemplate.returningFunction(`handleFunction(external.get, data[1], getScope, 0, onFactory, first)`, '_, external, first')};`, | ||
`var onFactory = ${runtimeTemplate.basicFunction('factory', [ | ||
'data.p = 1;', | ||
`${RuntimeGlobals.moduleFactories}[id] = ${runtimeTemplate.basicFunction('module', [ | ||
'module.exports = factory();', | ||
])}`, | ||
])};`, | ||
`handleFunction(${RuntimeGlobals.require}, data[2], 0, 0, onExternal, 1);`, | ||
])});`, | ||
]), | ||
'}', | ||
`${federationGlobal}.bundlerRuntime.remotes({idToRemoteMap,chunkMapping, idToExternalAndNameMapping, chunkId, promises, webpackRequire:${RuntimeGlobals.require}});`, | ||
// `if(${RuntimeGlobals.hasOwnProperty}(chunkMapping, chunkId)) {`, | ||
// Template.indent([ | ||
// `chunkMapping[chunkId].forEach(${runtimeTemplate.basicFunction('id', [ | ||
// `var getScope = ${RuntimeGlobals.currentRemoteGetScope};`, | ||
// 'if(!getScope) getScope = [];', | ||
// 'var data = idToExternalAndNameMapping[id];', | ||
// 'if(getScope.indexOf(data) >= 0) return;', | ||
// 'getScope.push(data);', | ||
// `if(data.p) return promises.push(data.p);`, | ||
// `var onError = ${runtimeTemplate.basicFunction('error', [ | ||
// 'if(!error) error = new Error("Container missing");', | ||
// 'if(typeof error.message === "string")', | ||
// Template.indent( | ||
// `error.message += '\\nwhile loading "' + data[1] + '" from ' + data[2];`, | ||
// ), | ||
// `${ | ||
// RuntimeGlobals.moduleFactories | ||
// }[id] = ${runtimeTemplate.basicFunction('', ['throw error;'])}`, | ||
// 'data.p = 0;', | ||
// ])};`, | ||
// `var handleFunction = ${runtimeTemplate.basicFunction( | ||
// 'fn, arg1, arg2, d, next, first', | ||
// [ | ||
// 'try {', | ||
// Template.indent([ | ||
// 'var promise = fn(arg1, arg2);', | ||
// 'if(promise && promise.then) {', | ||
// Template.indent([ | ||
// `var p = promise.then(${runtimeTemplate.returningFunction( | ||
// 'next(result, d)', | ||
// 'result', | ||
// )}, onError);`, | ||
// `if(first) promises.push(data.p = p); else return p;`, | ||
// ]), | ||
// '} else {', | ||
// Template.indent(['return next(promise, d, first);']), | ||
// '}', | ||
// ]), | ||
// '} catch(error) {', | ||
// Template.indent(['onError(error);']), | ||
// '}', | ||
// ], | ||
// )}`, | ||
// `var onExternal = ${runtimeTemplate.returningFunction( | ||
// `external ? handleFunction(${RuntimeGlobals.initializeSharing}, data[0], 0, external, onInitialized, first) : onError()`, | ||
// 'external, _, first', | ||
// )};`, | ||
// `var onInitialized = ${runtimeTemplate.returningFunction( | ||
// `handleFunction(external.get, data[1], getScope, 0, onFactory, first)`, | ||
// '_, external, first', | ||
// )};`, | ||
// `var onFactory = ${runtimeTemplate.basicFunction('factory', [ | ||
// 'data.p = 1;', | ||
// `${ | ||
// RuntimeGlobals.moduleFactories | ||
// }[id] = ${runtimeTemplate.basicFunction('module', [ | ||
// 'module.exports = factory();', | ||
// ])}`, | ||
// ])};`, | ||
// `handleFunction(${RuntimeGlobals.require}, data[2], 0, 0, onExternal, 1);`, | ||
// ])});`, | ||
// ]), | ||
// '}', | ||
])}`, | ||
@@ -103,0 +155,0 @@ ]); |
@@ -12,5 +12,6 @@ /* | ||
const ConsumeSharedFallbackDependency_1 = __importDefault(require("./ConsumeSharedFallbackDependency")); | ||
const utils_1 = require("./utils"); | ||
const Constants_1 = require("../Constants"); | ||
const { rangeToString, stringifyHoley } = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack/lib/util/semver')); | ||
const { AsyncDependenciesBlock, Module, RuntimeGlobals } = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack')); | ||
const { WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE } = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack/lib/ModuleTypeConstants')); | ||
const { sources: webpackSources } = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack')); | ||
@@ -37,3 +38,3 @@ const makeSerializable = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack/lib/util/makeSerializable')); | ||
constructor(context, options) { | ||
super(WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE, context); | ||
super(Constants_1.WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE, context); | ||
this.options = options; | ||
@@ -46,3 +47,3 @@ } | ||
const { shareKey, shareScope, importResolved, requiredVersion, strictVersion, singleton, eager, } = this.options; | ||
return `${WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE}|${shareScope}|${shareKey}|${requiredVersion && rangeToString(requiredVersion)}|${strictVersion}|${importResolved}|${singleton}|${eager}`; | ||
return `${Constants_1.WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE}|${shareScope}|${shareKey}|${requiredVersion && rangeToString(requiredVersion)}|${strictVersion}|${importResolved}|${singleton}|${eager}`; | ||
} | ||
@@ -177,8 +178,11 @@ /** | ||
} | ||
const code = runtimeTemplate.returningFunction(`${fn}(${args.join(', ')})`); | ||
// const code = runtimeTemplate.returningFunction(`${fn}(${args.join(', ')})`); | ||
const sources = new Map(); | ||
sources.set('consume-shared', new webpackSources.RawSource(code)); | ||
sources.set('consume-shared', new webpackSources.RawSource(fallbackCode || '()=>()=>{}')); | ||
const data = new Map(); | ||
data.set('consume-shared', (0, utils_1.normalizeConsumeShareOptions)(this.options)); | ||
return { | ||
runtimeRequirements, | ||
sources, | ||
data, | ||
}; | ||
@@ -185,0 +189,0 @@ } |
@@ -18,2 +18,4 @@ /* | ||
const ProvideForSharedDependency_1 = __importDefault(require("./ProvideForSharedDependency")); | ||
const FederationRuntimePlugin_1 = __importDefault(require("../container/runtime/FederationRuntimePlugin")); | ||
const ShareRuntimeModule_1 = __importDefault(require("./ShareRuntimeModule")); | ||
const { parseRange } = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack/lib/util/semver')); | ||
@@ -62,3 +64,4 @@ const ModuleNotFoundError = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack/lib/ModuleNotFoundError')); | ||
shareKey: key, | ||
requiredVersion: parseRange(item), | ||
// webpack internal semver has some issue, use runtime semver , related issue: https://github.com/webpack/webpack/issues/17756 | ||
requiredVersion: item, | ||
strictVersion: true, | ||
@@ -74,5 +77,4 @@ packageName: undefined, | ||
shareKey: item.shareKey || key, | ||
requiredVersion: typeof item.requiredVersion === 'string' | ||
? parseRange(item.requiredVersion) | ||
: item.requiredVersion, | ||
// @ts-ignore webpack internal semver has some issue, use runtime semver , related issue: https://github.com/webpack/webpack/issues/17756 | ||
requiredVersion: item.requiredVersion, | ||
strictVersion: typeof item.strictVersion === 'boolean' | ||
@@ -88,2 +90,4 @@ ? item.strictVersion | ||
apply(compiler) { | ||
//@ts-ignore | ||
new FederationRuntimePlugin_1.default().apply(compiler); | ||
process.env['FEDERATION_WEBPACK_PATH'] = | ||
@@ -175,3 +179,4 @@ process.env['FEDERATION_WEBPACK_PATH'] || (0, normalize_webpack_path_1.getWebpackPath)(compiler); | ||
} | ||
resolve(parseRange(requiredVersion)); | ||
// @ts-ignore webpack internal semver has some issue, use runtime semver , related issue: https://github.com/webpack/webpack/issues/17756 | ||
resolve(requiredVersion); | ||
}); | ||
@@ -238,2 +243,4 @@ }), | ||
new ConsumeSharedRuntimeModule_1.default(set)); | ||
// FIXME: need to remove webpack internal inject ShareRuntimeModule, otherwise there will be two ShareRuntimeModule | ||
compilation.addRuntimeModule(chunk, new ShareRuntimeModule_1.default()); | ||
}); | ||
@@ -240,0 +247,0 @@ }); |
@@ -8,2 +8,3 @@ "use strict"; | ||
const normalize_webpack_path_1 = require("@module-federation/sdk/normalize-webpack-path"); | ||
const utils_1 = require("../container/runtime/utils"); | ||
const { Template, RuntimeGlobals, RuntimeModule } = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack')); | ||
@@ -41,7 +42,23 @@ const { parseVersionRuntimeCode, versionLtRuntimeCode, rangeToStringRuntimeCode, satisfyRuntimeCode, } = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack/lib/util/semver')); | ||
list.push(id); | ||
moduleIdToSourceMapping.set(id, | ||
const moduleGetter = codeGenerationResults.getSource( | ||
// @ts-ignore | ||
codeGenerationResults.getSource( | ||
module, chunk.runtime, 'consume-shared'); | ||
const shareOption = codeGenerationResults.getData( | ||
// @ts-ignore | ||
module, chunk.runtime, 'consume-shared')); | ||
module, chunk.runtime, 'consume-shared'); | ||
const sharedInfoAndHandlerStr = Template.asString([ | ||
'{', | ||
Template.indent([ | ||
`getter: ${moduleGetter.source().toString()},`, | ||
`shareInfo: {`, | ||
Template.indent([ | ||
`shareConfig: ${JSON.stringify(shareOption.shareConfig, null, 2)},`, | ||
`scope: [${JSON.stringify(shareOption.shareScope || 'default')}],`, | ||
]), | ||
'},', | ||
`shareKey: "${shareOption.shareKey}",`, | ||
]), | ||
'}', | ||
]); | ||
moduleIdToSourceMapping.set(id, sharedInfoAndHandlerStr); | ||
} | ||
@@ -66,129 +83,212 @@ }; | ||
return null; | ||
const federationGlobal = (0, utils_1.getFederationGlobalScope)(RuntimeGlobals); | ||
return Template.asString([ | ||
parseVersionRuntimeCode(runtimeTemplate), | ||
versionLtRuntimeCode(runtimeTemplate), | ||
rangeToStringRuntimeCode(runtimeTemplate), | ||
satisfyRuntimeCode(runtimeTemplate), | ||
`var ensureExistence = ${runtimeTemplate.basicFunction('scopeName, key', [ | ||
`var scope = ${RuntimeGlobals.shareScopeMap}[scopeName];`, | ||
`if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) throw new Error("Shared module " + key + " doesn't exist in shared scope " + scopeName);`, | ||
'return scope;', | ||
])};`, | ||
`var findVersion = ${runtimeTemplate.basicFunction('scope, key', [ | ||
'var versions = scope[key];', | ||
`var key = Object.keys(versions).reduce(${runtimeTemplate.basicFunction('a, b', ['return !a || versionLt(a, b) ? b : a;'])}, 0);`, | ||
'return key && versions[key]', | ||
])};`, | ||
`var findSingletonVersionKey = ${runtimeTemplate.basicFunction('scope, key', [ | ||
'var versions = scope[key];', | ||
`return Object.keys(versions).reduce(${runtimeTemplate.basicFunction('a, b', ['return !a || (!versions[a].loaded && versionLt(a, b)) ? b : a;'])}, 0);`, | ||
])};`, | ||
`var getInvalidSingletonVersionMessage = ${runtimeTemplate.basicFunction('scope, key, version, requiredVersion', [ | ||
`return "Unsatisfied version " + version + " from " + (version && scope[key][version].from) + " of shared singleton module " + key + " (required " + rangeToString(requiredVersion) + ")"`, | ||
])};`, | ||
`var getSingleton = ${runtimeTemplate.basicFunction('scope, scopeName, key, requiredVersion', [ | ||
'var version = findSingletonVersionKey(scope, key);', | ||
'return get(scope[key][version]);', | ||
])};`, | ||
`var getSingletonVersion = ${runtimeTemplate.basicFunction('scope, scopeName, key, requiredVersion', [ | ||
'var version = findSingletonVersionKey(scope, key);', | ||
'if (!satisfy(requiredVersion, version)) warn(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));', | ||
'return get(scope[key][version]);', | ||
])};`, | ||
`var getStrictSingletonVersion = ${runtimeTemplate.basicFunction('scope, scopeName, key, requiredVersion', [ | ||
'var version = findSingletonVersionKey(scope, key);', | ||
'if (!satisfy(requiredVersion, version)) ' + | ||
'throw new Error(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));', | ||
'return get(scope[key][version]);', | ||
])};`, | ||
`var findValidVersion = ${runtimeTemplate.basicFunction('scope, key, requiredVersion', [ | ||
'var versions = scope[key];', | ||
`var key = Object.keys(versions).reduce(${runtimeTemplate.basicFunction('a, b', [ | ||
'if (!satisfy(requiredVersion, b)) return a;', | ||
'return !a || versionLt(a, b) ? b : a;', | ||
])}, 0);`, | ||
'return key && versions[key]', | ||
])};`, | ||
`var getInvalidVersionMessage = ${runtimeTemplate.basicFunction('scope, scopeName, key, requiredVersion', [ | ||
'var versions = scope[key];', | ||
'return "No satisfying version (" + rangeToString(requiredVersion) + ") of shared module " + key + " found in shared scope " + scopeName + ".\\n" +', | ||
`\t"Available versions: " + Object.keys(versions).map(${runtimeTemplate.basicFunction('key', ['return key + " from " + versions[key].from;'])}).join(", ");`, | ||
])};`, | ||
`var getValidVersion = ${runtimeTemplate.basicFunction('scope, scopeName, key, requiredVersion', [ | ||
'var entry = findValidVersion(scope, key, requiredVersion);', | ||
'if(entry) return get(entry);', | ||
'throw new Error(getInvalidVersionMessage(scope, scopeName, key, requiredVersion));', | ||
])};`, | ||
`var warn = ${compilation.outputOptions.ignoreBrowserWarnings | ||
? runtimeTemplate.basicFunction('', '') | ||
: runtimeTemplate.basicFunction('msg', [ | ||
'if (typeof console !== "undefined" && console.warn) console.warn(msg);', | ||
])};`, | ||
`var warnInvalidVersion = ${runtimeTemplate.basicFunction('scope, scopeName, key, requiredVersion', [ | ||
'warn(getInvalidVersionMessage(scope, scopeName, key, requiredVersion));', | ||
])};`, | ||
`var get = ${runtimeTemplate.basicFunction('entry', [ | ||
'entry.loaded = 1;', | ||
'return entry.get()', | ||
])};`, | ||
`var init = ${runtimeTemplate.returningFunction(Template.asString([ | ||
'function(scopeName, a, b, c) {', | ||
Template.indent([ | ||
`var promise = ${RuntimeGlobals.initializeSharing}(scopeName);`, | ||
`if (promise && promise.then) return promise.then(fn.bind(fn, scopeName, ${RuntimeGlobals.shareScopeMap}[scopeName], a, b, c));`, | ||
`return fn(scopeName, ${RuntimeGlobals.shareScopeMap}[scopeName], a, b, c);`, | ||
]), | ||
'}', | ||
]), 'fn')};`, | ||
'', | ||
`var load = /*#__PURE__*/ init(${runtimeTemplate.basicFunction('scopeName, scope, key', [ | ||
'ensureExistence(scopeName, key);', | ||
'return get(findVersion(scope, key));', | ||
])});`, | ||
`var loadFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction('scopeName, scope, key, fallback', [ | ||
`return scope && ${RuntimeGlobals.hasOwnProperty}(scope, key) ? get(findVersion(scope, key)) : fallback();`, | ||
])});`, | ||
`var loadVersionCheck = /*#__PURE__*/ init(${runtimeTemplate.basicFunction('scopeName, scope, key, version', [ | ||
'ensureExistence(scopeName, key);', | ||
'return get(findValidVersion(scope, key, version) || warnInvalidVersion(scope, scopeName, key, version) || findVersion(scope, key));', | ||
])});`, | ||
`var loadSingleton = /*#__PURE__*/ init(${runtimeTemplate.basicFunction('scopeName, scope, key', [ | ||
'ensureExistence(scopeName, key);', | ||
'return getSingleton(scope, scopeName, key);', | ||
])});`, | ||
`var loadSingletonVersionCheck = /*#__PURE__*/ init(${runtimeTemplate.basicFunction('scopeName, scope, key, version', [ | ||
'ensureExistence(scopeName, key);', | ||
'return getSingletonVersion(scope, scopeName, key, version);', | ||
])});`, | ||
`var loadStrictVersionCheck = /*#__PURE__*/ init(${runtimeTemplate.basicFunction('scopeName, scope, key, version', [ | ||
'ensureExistence(scopeName, key);', | ||
'return getValidVersion(scope, scopeName, key, version);', | ||
])});`, | ||
`var loadStrictSingletonVersionCheck = /*#__PURE__*/ init(${runtimeTemplate.basicFunction('scopeName, scope, key, version', [ | ||
'ensureExistence(scopeName, key);', | ||
'return getStrictSingletonVersion(scope, scopeName, key, version);', | ||
])});`, | ||
`var loadVersionCheckFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction('scopeName, scope, key, version, fallback', [ | ||
`if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) return fallback();`, | ||
'return get(findValidVersion(scope, key, version) || warnInvalidVersion(scope, scopeName, key, version) || findVersion(scope, key));', | ||
])});`, | ||
`var loadSingletonFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction('scopeName, scope, key, fallback', [ | ||
`if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) return fallback();`, | ||
'return getSingleton(scope, scopeName, key);', | ||
])});`, | ||
`var loadSingletonVersionCheckFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction('scopeName, scope, key, version, fallback', [ | ||
`if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) return fallback();`, | ||
'return getSingletonVersion(scope, scopeName, key, version);', | ||
])});`, | ||
`var loadStrictVersionCheckFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction('scopeName, scope, key, version, fallback', [ | ||
`var entry = scope && ${RuntimeGlobals.hasOwnProperty}(scope, key) && findValidVersion(scope, key, version);`, | ||
`return entry ? get(entry) : fallback();`, | ||
])});`, | ||
`var loadStrictSingletonVersionCheckFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction('scopeName, scope, key, version, fallback', [ | ||
`if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) return fallback();`, | ||
'return getStrictSingletonVersion(scope, scopeName, key, version);', | ||
])});`, | ||
// parseVersionRuntimeCode(runtimeTemplate), | ||
// versionLtRuntimeCode(runtimeTemplate), | ||
// rangeToStringRuntimeCode(runtimeTemplate), | ||
// satisfyRuntimeCode(runtimeTemplate), | ||
// `var ensureExistence = ${runtimeTemplate.basicFunction('scopeName, key', [ | ||
// `var scope = ${RuntimeGlobals.shareScopeMap}[scopeName];`, | ||
// `if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) throw new Error("Shared module " + key + " doesn't exist in shared scope " + scopeName);`, | ||
// 'return scope;', | ||
// ])};`, | ||
// `var findVersion = ${runtimeTemplate.basicFunction('scope, key', [ | ||
// 'var versions = scope[key];', | ||
// `var key = Object.keys(versions).reduce(${runtimeTemplate.basicFunction( | ||
// 'a, b', | ||
// ['return !a || versionLt(a, b) ? b : a;'], | ||
// )}, 0);`, | ||
// 'return key && versions[key]', | ||
// ])};`, | ||
// `var findSingletonVersionKey = ${runtimeTemplate.basicFunction( | ||
// 'scope, key', | ||
// [ | ||
// 'var versions = scope[key];', | ||
// `return Object.keys(versions).reduce(${runtimeTemplate.basicFunction( | ||
// 'a, b', | ||
// ['return !a || (!versions[a].loaded && versionLt(a, b)) ? b : a;'], | ||
// )}, 0);`, | ||
// ], | ||
// )};`, | ||
// `var getInvalidSingletonVersionMessage = ${runtimeTemplate.basicFunction( | ||
// 'scope, key, version, requiredVersion', | ||
// [ | ||
// `return "Unsatisfied version " + version + " from " + (version && scope[key][version].from) + " of shared singleton module " + key + " (required " + rangeToString(requiredVersion) + ")"`, | ||
// ], | ||
// )};`, | ||
// `var getSingleton = ${runtimeTemplate.basicFunction( | ||
// 'scope, scopeName, key, requiredVersion', | ||
// [ | ||
// 'var version = findSingletonVersionKey(scope, key);', | ||
// 'return get(scope[key][version]);', | ||
// ], | ||
// )};`, | ||
// `var getSingletonVersion = ${runtimeTemplate.basicFunction( | ||
// 'scope, scopeName, key, requiredVersion', | ||
// [ | ||
// 'var version = findSingletonVersionKey(scope, key);', | ||
// 'if (!satisfy(requiredVersion, version)) warn(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));', | ||
// 'return get(scope[key][version]);', | ||
// ], | ||
// )};`, | ||
// `var getStrictSingletonVersion = ${runtimeTemplate.basicFunction( | ||
// 'scope, scopeName, key, requiredVersion', | ||
// [ | ||
// 'var version = findSingletonVersionKey(scope, key);', | ||
// 'if (!satisfy(requiredVersion, version)) ' + | ||
// 'throw new Error(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));', | ||
// 'return get(scope[key][version]);', | ||
// ], | ||
// )};`, | ||
// `var findValidVersion = ${runtimeTemplate.basicFunction( | ||
// 'scope, key, requiredVersion', | ||
// [ | ||
// 'var versions = scope[key];', | ||
// `var key = Object.keys(versions).reduce(${runtimeTemplate.basicFunction( | ||
// 'a, b', | ||
// [ | ||
// 'if (!satisfy(requiredVersion, b)) return a;', | ||
// 'return !a || versionLt(a, b) ? b : a;', | ||
// ], | ||
// )}, 0);`, | ||
// 'return key && versions[key]', | ||
// ], | ||
// )};`, | ||
// `var getInvalidVersionMessage = ${runtimeTemplate.basicFunction( | ||
// 'scope, scopeName, key, requiredVersion', | ||
// [ | ||
// 'var versions = scope[key];', | ||
// 'return "No satisfying version (" + rangeToString(requiredVersion) + ") of shared module " + key + " found in shared scope " + scopeName + ".\\n" +', | ||
// `\t"Available versions: " + Object.keys(versions).map(${runtimeTemplate.basicFunction( | ||
// 'key', | ||
// ['return key + " from " + versions[key].from;'], | ||
// )}).join(", ");`, | ||
// ], | ||
// )};`, | ||
// `var getValidVersion = ${runtimeTemplate.basicFunction( | ||
// 'scope, scopeName, key, requiredVersion', | ||
// [ | ||
// 'var entry = findValidVersion(scope, key, requiredVersion);', | ||
// 'if(entry) return get(entry);', | ||
// 'throw new Error(getInvalidVersionMessage(scope, scopeName, key, requiredVersion));', | ||
// ], | ||
// )};`, | ||
// `var warn = ${ | ||
// compilation.outputOptions.ignoreBrowserWarnings | ||
// ? runtimeTemplate.basicFunction('', '') | ||
// : runtimeTemplate.basicFunction('msg', [ | ||
// 'if (typeof console !== "undefined" && console.warn) console.warn(msg);', | ||
// ]) | ||
// };`, | ||
// `var warnInvalidVersion = ${runtimeTemplate.basicFunction( | ||
// 'scope, scopeName, key, requiredVersion', | ||
// [ | ||
// 'warn(getInvalidVersionMessage(scope, scopeName, key, requiredVersion));', | ||
// ], | ||
// )};`, | ||
// `var get = ${runtimeTemplate.basicFunction('entry', [ | ||
// 'entry.loaded = 1;', | ||
// 'return entry.get()', | ||
// ])};`, | ||
// `var init = ${runtimeTemplate.returningFunction( | ||
// Template.asString([ | ||
// 'function(scopeName, a, b, c) {', | ||
// Template.indent([ | ||
// `var promise = ${RuntimeGlobals.initializeSharing}(scopeName);`, | ||
// `if (promise && promise.then) return promise.then(fn.bind(fn, scopeName, ${RuntimeGlobals.shareScopeMap}[scopeName], a, b, c));`, | ||
// `return fn(scopeName, ${RuntimeGlobals.shareScopeMap}[scopeName], a, b, c);`, | ||
// ]), | ||
// '}', | ||
// ]), | ||
// 'fn', | ||
// )};`, | ||
// '', | ||
// `var load = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( | ||
// 'scopeName, scope, key', | ||
// [ | ||
// 'ensureExistence(scopeName, key);', | ||
// 'return get(findVersion(scope, key));', | ||
// ], | ||
// )});`, | ||
// `var loadFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( | ||
// 'scopeName, scope, key, fallback', | ||
// [ | ||
// `return scope && ${RuntimeGlobals.hasOwnProperty}(scope, key) ? get(findVersion(scope, key)) : fallback();`, | ||
// ], | ||
// )});`, | ||
// `var loadVersionCheck = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( | ||
// 'scopeName, scope, key, version', | ||
// [ | ||
// 'ensureExistence(scopeName, key);', | ||
// 'return get(findValidVersion(scope, key, version) || warnInvalidVersion(scope, scopeName, key, version) || findVersion(scope, key));', | ||
// ], | ||
// )});`, | ||
// `var loadSingleton = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( | ||
// 'scopeName, scope, key', | ||
// [ | ||
// 'ensureExistence(scopeName, key);', | ||
// 'return getSingleton(scope, scopeName, key);', | ||
// ], | ||
// )});`, | ||
// `var loadSingletonVersionCheck = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( | ||
// 'scopeName, scope, key, version', | ||
// [ | ||
// 'ensureExistence(scopeName, key);', | ||
// 'return getSingletonVersion(scope, scopeName, key, version);', | ||
// ], | ||
// )});`, | ||
// `var loadStrictVersionCheck = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( | ||
// 'scopeName, scope, key, version', | ||
// [ | ||
// 'ensureExistence(scopeName, key);', | ||
// 'return getValidVersion(scope, scopeName, key, version);', | ||
// ], | ||
// )});`, | ||
// `var loadStrictSingletonVersionCheck = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( | ||
// 'scopeName, scope, key, version', | ||
// [ | ||
// 'ensureExistence(scopeName, key);', | ||
// 'return getStrictSingletonVersion(scope, scopeName, key, version);', | ||
// ], | ||
// )});`, | ||
// `var loadVersionCheckFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( | ||
// 'scopeName, scope, key, version, fallback', | ||
// [ | ||
// `if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) return fallback();`, | ||
// 'return get(findValidVersion(scope, key, version) || warnInvalidVersion(scope, scopeName, key, version) || findVersion(scope, key));', | ||
// ], | ||
// )});`, | ||
// `var loadSingletonFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( | ||
// 'scopeName, scope, key, fallback', | ||
// [ | ||
// `if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) return fallback();`, | ||
// 'return getSingleton(scope, scopeName, key);', | ||
// ], | ||
// )});`, | ||
// `var loadSingletonVersionCheckFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( | ||
// 'scopeName, scope, key, version, fallback', | ||
// [ | ||
// `if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) return fallback();`, | ||
// 'return getSingletonVersion(scope, scopeName, key, version);', | ||
// ], | ||
// )});`, | ||
// `var loadStrictVersionCheckFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( | ||
// 'scopeName, scope, key, version, fallback', | ||
// [ | ||
// `var entry = scope && ${RuntimeGlobals.hasOwnProperty}(scope, key) && findValidVersion(scope, key, version);`, | ||
// `return entry ? get(entry) : fallback();`, | ||
// ], | ||
// )});`, | ||
// `var loadStrictSingletonVersionCheckFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( | ||
// 'scopeName, scope, key, version, fallback', | ||
// [ | ||
// `if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) return fallback();`, | ||
// 'return getStrictSingletonVersion(scope, scopeName, key, version);', | ||
// ], | ||
// )});`, | ||
'var installedModules = {};', | ||
'var moduleToHandlerMapping = {', | ||
Template.indent(Array.from(moduleIdToSourceMapping, ([key, source]) => `${JSON.stringify(key)}: ${source.source()}`).join(',\n')), | ||
Template.indent(Array.from(moduleIdToSourceMapping, ([key, value]) => { | ||
return `${JSON.stringify(key)}: ${value}`; | ||
}).join(',\n')), | ||
'};', | ||
@@ -198,12 +298,16 @@ initialConsumes.length > 0 | ||
`var initialConsumes = ${JSON.stringify(initialConsumes)};`, | ||
`initialConsumes.forEach(${runtimeTemplate.basicFunction('id', [ | ||
`${RuntimeGlobals.moduleFactories}[id] = ${runtimeTemplate.basicFunction('module', [ | ||
'// Handle case when module is used sync', | ||
'installedModules[id] = 0;', | ||
`delete ${RuntimeGlobals.moduleCache}[id];`, | ||
'var factory = moduleToHandlerMapping[id]();', | ||
'if(typeof factory !== "function") throw new Error("Shared module is not available for eager consumption: " + id);', | ||
`module.exports = factory();`, | ||
])}`, | ||
])});`, | ||
// FIXME: or set installInitialConsumesOptions into federationGlobal.xxOptions? | ||
`${federationGlobal}.installInitialConsumes= ()=>${federationGlobal}.bundlerRuntime.installInitialConsumes({initialConsumes, installedModules, moduleToHandlerMapping, webpackRequire:${RuntimeGlobals.require}});`, | ||
// `initialConsumes.forEach(${runtimeTemplate.basicFunction('id', [ | ||
// `${ | ||
// RuntimeGlobals.moduleFactories | ||
// }[id] = ${runtimeTemplate.basicFunction('module', [ | ||
// '// Handle case when module is used sync', | ||
// 'installedModules[id] = 0;', | ||
// `delete ${RuntimeGlobals.moduleCache}[id];`, | ||
// 'var factory = moduleToHandlerMapping[id]();', | ||
// 'if(typeof factory !== "function") throw new Error("Shared module is not available for eager consumption: " + id);', | ||
// `module.exports = factory();`, | ||
// ])}`, | ||
// ])});`, | ||
]) | ||
@@ -215,31 +319,44 @@ : '// no consumes in initial chunks', | ||
`${RuntimeGlobals.ensureChunkHandlers}.consumes = ${runtimeTemplate.basicFunction('chunkId, promises', [ | ||
`if(${RuntimeGlobals.hasOwnProperty}(chunkMapping, chunkId)) {`, | ||
Template.indent([ | ||
`chunkMapping[chunkId].forEach(${runtimeTemplate.basicFunction('id', [ | ||
`if(${RuntimeGlobals.hasOwnProperty}(installedModules, id)) return promises.push(installedModules[id]);`, | ||
`var onFactory = ${runtimeTemplate.basicFunction('factory', [ | ||
'installedModules[id] = 0;', | ||
`${RuntimeGlobals.moduleFactories}[id] = ${runtimeTemplate.basicFunction('module', [ | ||
`delete ${RuntimeGlobals.moduleCache}[id];`, | ||
'module.exports = factory();', | ||
])}`, | ||
])};`, | ||
`var onError = ${runtimeTemplate.basicFunction('error', [ | ||
'delete installedModules[id];', | ||
`${RuntimeGlobals.moduleFactories}[id] = ${runtimeTemplate.basicFunction('module', [ | ||
`delete ${RuntimeGlobals.moduleCache}[id];`, | ||
'throw error;', | ||
])}`, | ||
])};`, | ||
'try {', | ||
Template.indent([ | ||
'var promise = moduleToHandlerMapping[id]();', | ||
'if(promise.then) {', | ||
Template.indent("promises.push(installedModules[id] = promise.then(onFactory)['catch'](onError));"), | ||
'} else onFactory(promise);', | ||
]), | ||
'} catch(e) { onError(e); }', | ||
])});`, | ||
]), | ||
'}', | ||
`${federationGlobal}.bundlerRuntime.consumes({chunkMapping, installedModules, chunkId, moduleToHandlerMapping, promises, webpackRequire:${RuntimeGlobals.require}});`, | ||
// `if(${RuntimeGlobals.hasOwnProperty}(chunkMapping, chunkId)) {`, | ||
// Template.indent([ | ||
// `chunkMapping[chunkId].forEach(${runtimeTemplate.basicFunction( | ||
// 'id', | ||
// [ | ||
// `if(${RuntimeGlobals.hasOwnProperty}(installedModules, id)) return promises.push(installedModules[id]);`, | ||
// `var onFactory = ${runtimeTemplate.basicFunction( | ||
// 'factory', | ||
// [ | ||
// 'installedModules[id] = 0;', | ||
// `${ | ||
// RuntimeGlobals.moduleFactories | ||
// }[id] = ${runtimeTemplate.basicFunction('module', [ | ||
// `delete ${RuntimeGlobals.moduleCache}[id];`, | ||
// 'module.exports = factory();', | ||
// ])}`, | ||
// ], | ||
// )};`, | ||
// `var onError = ${runtimeTemplate.basicFunction('error', [ | ||
// 'delete installedModules[id];', | ||
// `${ | ||
// RuntimeGlobals.moduleFactories | ||
// }[id] = ${runtimeTemplate.basicFunction('module', [ | ||
// `delete ${RuntimeGlobals.moduleCache}[id];`, | ||
// 'throw error;', | ||
// ])}`, | ||
// ])};`, | ||
// 'try {', | ||
// Template.indent([ | ||
// 'var promise = moduleToHandlerMapping[id]();', | ||
// 'if(promise.then) {', | ||
// Template.indent( | ||
// "promises.push(installedModules[id] = promise.then(onFactory)['catch'](onError));", | ||
// ), | ||
// '} else onFactory(promise);', | ||
// ]), | ||
// '} catch(e) { onError(e); }', | ||
// ], | ||
// )});`, | ||
// ]), | ||
// '}', | ||
])}`, | ||
@@ -246,0 +363,0 @@ ]) |
@@ -12,5 +12,5 @@ "use strict"; | ||
const ProvideForSharedDependency_1 = __importDefault(require("./ProvideForSharedDependency")); | ||
const Constants_1 = require("../Constants"); | ||
const { AsyncDependenciesBlock, Module, RuntimeGlobals } = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack')); | ||
const makeSerializable = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack/lib/util/makeSerializable')); | ||
const { WEBPACK_MODULE_TYPE_PROVIDE } = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack/lib/ModuleTypeConstants')); | ||
const TYPES = new Set(['share-init']); | ||
@@ -31,3 +31,3 @@ /** | ||
constructor(shareScope, name, version, request, eager) { | ||
super(WEBPACK_MODULE_TYPE_PROVIDE); | ||
super(Constants_1.WEBPACK_MODULE_TYPE_PROVIDE); | ||
this._shareScope = shareScope; | ||
@@ -114,5 +114,5 @@ this._name = name; | ||
const runtimeRequirements = new Set([RuntimeGlobals.initializeSharing]); | ||
const code = `register(${JSON.stringify(this._name)}, ${JSON.stringify(this._version || '0')}, ${this._eager | ||
const moduleGetter = this._eager | ||
? runtimeTemplate.syncModuleFactory({ | ||
// @ts-ignore | ||
//@ts-ignore | ||
dependency: this.dependencies[0], | ||
@@ -124,3 +124,3 @@ chunkGraph, | ||
: runtimeTemplate.asyncModuleFactory({ | ||
// @ts-ignore | ||
//@ts-ignore | ||
block: this.blocks[0], | ||
@@ -130,3 +130,4 @@ chunkGraph, | ||
runtimeRequirements, | ||
})}${this._eager ? ', 1' : ''});`; | ||
}); | ||
const code = `register(${JSON.stringify(this._name)}, ${JSON.stringify(this._version || '0')}, ${moduleGetter}${this._eager ? ', 1' : ''});`; | ||
const sources = new Map(); | ||
@@ -141,2 +142,9 @@ const data = new Map(); | ||
]); | ||
data.set('share-init-option', { | ||
name: this._name, | ||
version: JSON.stringify(this._version || '0'), | ||
request: this._request, | ||
getter: moduleGetter, | ||
shareScope: [this._shareScope], | ||
}); | ||
return { sources, data, runtimeRequirements }; | ||
@@ -143,0 +151,0 @@ } |
@@ -15,2 +15,3 @@ /* | ||
const ProvideSharedModuleFactory_1 = __importDefault(require("./ProvideSharedModuleFactory")); | ||
const FederationRuntimePlugin_1 = __importDefault(require("../container/runtime/FederationRuntimePlugin")); | ||
const createSchemaValidation = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack/lib/util/create-schema-validation')); | ||
@@ -70,2 +71,3 @@ const WebpackError = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack/lib/WebpackError')); | ||
apply(compiler) { | ||
new FederationRuntimePlugin_1.default().apply(compiler); | ||
process.env['FEDERATION_WEBPACK_PATH'] = | ||
@@ -72,0 +74,0 @@ process.env['FEDERATION_WEBPACK_PATH'] || (0, normalize_webpack_path_1.getWebpackPath)(compiler); |
@@ -8,2 +8,3 @@ /* | ||
const normalize_webpack_path_1 = require("@module-federation/sdk/normalize-webpack-path"); | ||
const utils_1 = require("../container/runtime/utils"); | ||
const { Template, RuntimeGlobals, RuntimeModule } = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack')); | ||
@@ -13,3 +14,4 @@ const { compareModulesByIdentifier, compareStrings } = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack/lib/util/comparators')); | ||
constructor() { | ||
super('sharing'); | ||
// must after FederationRuntimeModule | ||
super('sharing', RuntimeModule.STAGE_NORMAL + 2); | ||
} | ||
@@ -30,2 +32,3 @@ /** | ||
const initCodePerScope = new Map(); | ||
let sharedInitOptionsStr = ''; | ||
for (const chunk of this.chunk?.getAllReferencedChunks() || []) { | ||
@@ -56,5 +59,17 @@ if (!chunk) { | ||
} | ||
const sharedOption = codeGenerationResults.getData(m, chunk.runtime, 'share-init-option'); | ||
if (sharedOption) { | ||
sharedInitOptionsStr += ` | ||
"${sharedOption.name}" : { | ||
version: ${sharedOption.version}, | ||
get: ${sharedOption.getter}, | ||
scope: ${JSON.stringify(sharedOption.shareScope)} | ||
}, | ||
`; | ||
} | ||
} | ||
} | ||
const federationGlobal = (0, utils_1.getFederationGlobalScope)(RuntimeGlobals || {}); | ||
return Template.asString([ | ||
`${(0, utils_1.getFederationGlobalScope)(RuntimeGlobals)}.initOptions.shared = {${sharedInitOptionsStr}}`, | ||
`${RuntimeGlobals.shareScopeMap} = {};`, | ||
@@ -64,53 +79,74 @@ 'var initPromises = {};', | ||
`${RuntimeGlobals.initializeSharing} = ${runtimeTemplate.basicFunction('name, initScope', [ | ||
'if(!initScope) initScope = [];', | ||
'// handling circular init calls', | ||
'var initToken = initTokens[name];', | ||
'if(!initToken) initToken = initTokens[name] = {};', | ||
'if(initScope.indexOf(initToken) >= 0) return;', | ||
'initScope.push(initToken);', | ||
'// only runs once', | ||
'if(initPromises[name]) return initPromises[name];', | ||
'// creates a new share scope if needed', | ||
`if(!${RuntimeGlobals.hasOwnProperty}(${RuntimeGlobals.shareScopeMap}, name)) ${RuntimeGlobals.shareScopeMap}[name] = {};`, | ||
'// runs all init snippets from all modules reachable', | ||
`var scope = ${RuntimeGlobals.shareScopeMap}[name];`, | ||
`var warn = ${ignoreBrowserWarnings | ||
? runtimeTemplate.basicFunction('', '') | ||
: runtimeTemplate.basicFunction('msg', [ | ||
'if (typeof console !== "undefined" && console.warn) console.warn(msg);', | ||
])};`, | ||
`var uniqueName = ${JSON.stringify(uniqueName || undefined)};`, | ||
`var register = ${runtimeTemplate.basicFunction('name, version, factory, eager', [ | ||
'var versions = scope[name] = scope[name] || {};', | ||
'var activeVersion = versions[version];', | ||
'if(!activeVersion || (!activeVersion.loaded && (!eager != !activeVersion.eager ? eager : uniqueName > activeVersion.from))) versions[version] = { get: factory, from: uniqueName, eager: !!eager };', | ||
])};`, | ||
`var initExternal = ${runtimeTemplate.basicFunction('id', [ | ||
`var handleError = ${runtimeTemplate.expressionFunction('warn("Initialization of sharing external failed: " + err)', 'err')};`, | ||
'try {', | ||
Template.indent([ | ||
`var module = ${RuntimeGlobals.require}(id);`, | ||
'if(!module) return;', | ||
`var initFn = ${runtimeTemplate.returningFunction(`module && module.init && module.init(${RuntimeGlobals.shareScopeMap}[name], initScope)`, 'module')}`, | ||
'if(module.then) return promises.push(module.then(initFn, handleError));', | ||
'var initResult = initFn(module);', | ||
"if(initResult && initResult.then) return promises.push(initResult['catch'](handleError));", | ||
]), | ||
'} catch(err) { handleError(err); }', | ||
`return ${federationGlobal}.bundlerRuntime.I({${Template.indent([ | ||
`shareScopeName: name,`, | ||
`webpackRequire: ${RuntimeGlobals.require},`, | ||
`initPromises: initPromises,`, | ||
`initTokens: initTokens,`, | ||
`initScope: initScope,`, | ||
])}`, | ||
'var promises = [];', | ||
'switch(name) {', | ||
...Array.from(initCodePerScope) | ||
.sort(([a], [b]) => compareStrings(a, b)) | ||
.map(([name, stages]) => Template.indent([ | ||
`case ${JSON.stringify(name)}: {`, | ||
Template.indent(Array.from(stages) | ||
.sort(([a], [b]) => a - b) | ||
.map(([, initCode]) => Template.asString(Array.from(initCode)))), | ||
'}', | ||
'break;', | ||
])), | ||
'}', | ||
'if(!promises.length) return initPromises[name] = 1;', | ||
`return initPromises[name] = Promise.all(promises).then(${runtimeTemplate.returningFunction('initPromises[name] = 1')});`, | ||
'})', | ||
// '// only runs once', | ||
// 'if(initPromises[name]) return initPromises[name];', | ||
// '// creates a new share scope if needed', | ||
// `if(!${RuntimeGlobals.hasOwnProperty}(${RuntimeGlobals.shareScopeMap}, name)) ${RuntimeGlobals.shareScopeMap}[name] = {};`, | ||
// '// runs all init snippets from all modules reachable', | ||
// `var scope = ${RuntimeGlobals.shareScopeMap}[name];`, | ||
// `var warn = ${ | ||
// ignoreBrowserWarnings | ||
// ? runtimeTemplate.basicFunction('', '') | ||
// : runtimeTemplate.basicFunction('msg', [ | ||
// 'if (typeof console !== "undefined" && console.warn) console.warn(msg);', | ||
// ]) | ||
// };`, | ||
// `var uniqueName = ${JSON.stringify(uniqueName || undefined)};`, | ||
// `var register = ${runtimeTemplate.basicFunction( | ||
// 'name, version, factory, eager', | ||
// [ | ||
// 'var versions = scope[name] = scope[name] || {};', | ||
// 'var activeVersion = versions[version];', | ||
// 'if(!activeVersion || (!activeVersion.loaded && (!eager != !activeVersion.eager ? eager : uniqueName > activeVersion.from))) versions[version] = { get: factory, from: uniqueName, eager: !!eager };', | ||
// ], | ||
// )};`, | ||
// `var initExternal = ${runtimeTemplate.basicFunction('id', [ | ||
// `var handleError = ${runtimeTemplate.expressionFunction( | ||
// 'warn("Initialization of sharing external failed: " + err)', | ||
// 'err', | ||
// )};`, | ||
// 'try {', | ||
// Template.indent([ | ||
// `var module = ${RuntimeGlobals.require}(id);`, | ||
// 'if(!module) return;', | ||
// `var initFn = ${runtimeTemplate.returningFunction( | ||
// `module && module.init && module.init(${RuntimeGlobals.shareScopeMap}[name], initScope)`, | ||
// 'module', | ||
// )}`, | ||
// 'if(module.then) return promises.push(module.then(initFn, handleError));', | ||
// 'var initResult = initFn(module);', | ||
// "if(initResult && initResult.then) return promises.push(initResult['catch'](handleError));", | ||
// ]), | ||
// '} catch(err) { handleError(err); }', | ||
// ])}`, | ||
// 'var promises = [];', | ||
// 'switch(name) {', | ||
// ...Array.from(initCodePerScope) | ||
// .sort(([a], [b]) => compareStrings(a, b)) | ||
// .map(([name, stages]) => | ||
// Template.indent([ | ||
// `case ${JSON.stringify(name)}: {`, | ||
// Template.indent( | ||
// Array.from(stages) | ||
// .sort(([a], [b]) => a - b) | ||
// .map(([, initCode]) => | ||
// Template.asString(Array.from(initCode)), | ||
// ), | ||
// ), | ||
// '}', | ||
// 'break;', | ||
// ]), | ||
// ), | ||
// '}', | ||
// 'if(!promises.length) return initPromises[name] = 1;', | ||
// `return initPromises[name] = Promise.all(promises).then(${runtimeTemplate.returningFunction( | ||
// 'initPromises[name] = 1', | ||
// )});`, | ||
])};`, | ||
@@ -117,0 +153,0 @@ ]); |
@@ -0,1 +1,2 @@ | ||
import type { ConsumeOptions } from 'webpack/lib/sharing/ConsumeSharedModule'; | ||
import type { InputFileSystem } from 'webpack/lib/util/fs'; | ||
@@ -34,1 +35,12 @@ /** | ||
export declare function getRequiredVersionFromDescriptionFile(data: Record<string, any>, packageName: string): string | undefined | void; | ||
export declare function normalizeConsumeShareOptions(consumeOptions: ConsumeOptions): { | ||
shareConfig: { | ||
fixedDependencies: boolean; | ||
requiredVersion: false | import("../../../../../webpack/lib/util/semver").SemVerRange; | ||
strictVersion: boolean; | ||
singleton: boolean; | ||
eager: boolean; | ||
}; | ||
shareScope: string; | ||
shareKey: string; | ||
}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getRequiredVersionFromDescriptionFile = exports.getDescriptionFile = exports.normalizeVersion = exports.isRequiredVersion = void 0; | ||
/* | ||
@@ -8,2 +6,4 @@ MIT License http://www.opensource.org/licenses/mit-license.php | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.normalizeConsumeShareOptions = exports.getRequiredVersionFromDescriptionFile = exports.getDescriptionFile = exports.normalizeVersion = exports.isRequiredVersion = void 0; | ||
const normalize_webpack_path_1 = require("@module-federation/sdk/normalize-webpack-path"); | ||
@@ -345,2 +345,17 @@ const { join, dirname, readJson } = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack/lib/util/fs')); | ||
exports.getRequiredVersionFromDescriptionFile = getRequiredVersionFromDescriptionFile; | ||
function normalizeConsumeShareOptions(consumeOptions) { | ||
const { requiredVersion = false, strictVersion, singleton = false, eager, shareKey, shareScope, } = consumeOptions; | ||
return { | ||
shareConfig: { | ||
fixedDependencies: false, | ||
requiredVersion, | ||
strictVersion, | ||
singleton, | ||
eager, | ||
}, | ||
shareScope, | ||
shareKey, | ||
}; | ||
} | ||
exports.normalizeConsumeShareOptions = normalizeConsumeShareOptions; | ||
//# sourceMappingURL=utils.js.map |
@@ -1,2 +0,2 @@ | ||
declare function D(n: any, { instancePath: s, parentData, parentDataProperty, rootData: l, }?: { | ||
declare function validate48(data: any, { instancePath, parentData, parentDataProperty, rootData }?: { | ||
instancePath?: string | undefined; | ||
@@ -6,3 +6,3 @@ parentData: any; | ||
rootData?: any; | ||
}): any; | ||
export default D; | ||
}): boolean; | ||
export default validate48; |
@@ -407,6 +407,2 @@ declare const _default: { | ||
}; | ||
async: { | ||
description: string; | ||
type: string; | ||
}; | ||
name: { | ||
@@ -428,2 +424,10 @@ description: string; | ||
}; | ||
runtimePlugins: { | ||
type: string; | ||
items: { | ||
description: string; | ||
type: string; | ||
minLength: number; | ||
}; | ||
}; | ||
shareScope: { | ||
@@ -430,0 +434,0 @@ description: string; |
@@ -497,6 +497,2 @@ "use strict"; | ||
}, | ||
async: { | ||
description: 'Enable async loading of entry chunks.', | ||
type: 'boolean', | ||
}, | ||
name: { | ||
@@ -520,2 +516,10 @@ description: 'The name of the container.', | ||
}, | ||
runtimePlugins: { | ||
type: 'array', | ||
items: { | ||
description: 'Runtime Plugin File Path.', | ||
type: 'string', | ||
minLength: 1, | ||
}, | ||
}, | ||
shareScope: { | ||
@@ -522,0 +526,0 @@ description: "Share scope name used for all shared modules (defaults to 'default').", |
{ | ||
"name": "@module-federation/enhanced", | ||
"version": "0.0.0-next-20231220085130", | ||
"version": "0.0.0-next-20231221061836", | ||
"type": "commonjs", | ||
@@ -31,4 +31,6 @@ "main": "./dist/src/index.js", | ||
"dependencies": { | ||
"@module-federation/sdk": "0.0.0-next-20231220085130" | ||
"@module-federation/sdk": "0.0.0-next-20231221061836", | ||
"@module-federation/runtime": "0.0.0-next-20231221061836", | ||
"@module-federation/webpack-bundler-runtime": "0.0.0-next-20231221061836" | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
871367
151
14616
4
80
+ Added@module-federation/webpack-bundler-runtime@0.0.0-next-20231221061836
+ Added@module-federation/runtime@0.0.0-next-20231221061836(transitive)
+ Added@module-federation/sdk@0.0.0-next-20231221061836(transitive)
+ Added@module-federation/webpack-bundler-runtime@0.0.0-next-20231221061836(transitive)
- Removed@module-federation/sdk@0.0.0-next-20231220085130(transitive)