@module-federation/enhanced
Advanced tools
Comparing version 0.0.0-next-20240227135200 to 0.0.0-next-20240228024304
@@ -36,4 +36,2 @@ { | ||
"@module-federation/runtime-tools": "workspace:*", | ||
"@module-federation/manifest": "workspace:*", | ||
"@module-federation/managers": "workspace:*", | ||
"upath": "2.0.1" | ||
@@ -40,0 +38,0 @@ }, |
@@ -119,5 +119,2 @@ /* | ||
new StaticExportsDependency(['get', 'init'], false)); | ||
this.addDependency( | ||
// @ts-ignore | ||
new EntryDependency(this._injectRuntimeEntry)); | ||
callback(); | ||
@@ -173,11 +170,2 @@ } | ||
} | ||
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 || {}); | ||
@@ -213,3 +201,2 @@ const source = Template.asString([ | ||
])};`, | ||
`${initRuntimeModuleGetter}`, | ||
'', | ||
@@ -216,0 +203,0 @@ '// This exports getters to disallow modifications', |
@@ -1,13 +0,34 @@ | ||
import type { Compiler } from 'webpack'; | ||
import type { containerPlugin } from '@module-federation/sdk'; | ||
export = ContainerPlugin; | ||
declare class ContainerPlugin { | ||
_options: containerPlugin.ContainerPluginOptions; | ||
/** | ||
* @param {ContainerPluginOptions} options options | ||
*/ | ||
constructor(options: ContainerPluginOptions); | ||
name: string; | ||
_options: { | ||
name: string; | ||
/** | ||
* @param {containerPlugin.ContainerPluginOptions} options options | ||
*/ | ||
constructor(options: containerPlugin.ContainerPluginOptions); | ||
static patchChunkSplit(compiler: Compiler, name: string): void; | ||
apply(compiler: Compiler): void; | ||
shareScope: string; | ||
library: import('../../declarations/plugins/container/ContainerPlugin').LibraryOptions; | ||
runtime: import('../../declarations/plugins/container/ContainerPlugin').EntryRuntime; | ||
filename: string; | ||
exposes: [ | ||
string, | ||
{ | ||
import: string[]; | ||
name: any; | ||
}, | ||
][]; | ||
}; | ||
/** | ||
* Apply the plugin | ||
* @param {Compiler} compiler the compiler instance | ||
* @returns {void} | ||
*/ | ||
apply(compiler: Compiler): void; | ||
} | ||
export default ContainerPlugin; | ||
declare namespace ContainerPlugin { | ||
export { ContainerPluginOptions, Compiler }; | ||
} | ||
type Compiler = import('webpack/lib/Compiler'); | ||
type ContainerPluginOptions = | ||
import('../../declarations/plugins/container/ContainerPlugin').ContainerPluginOptions; |
@@ -26,3 +26,3 @@ "use strict"; | ||
/** | ||
* @param {containerPlugin.ContainerPluginOptions} options options | ||
* @param {ContainerPluginOptions} options options | ||
*/ | ||
@@ -135,2 +135,7 @@ constructor(options) { | ||
} | ||
const hasSingleRuntimeChunk = compiler.options?.optimization?.runtimeChunk; | ||
new compiler.webpack.EntryPlugin(compiler.options.context || '', federationRuntimePluginInstance.entryFilePath, { | ||
name, | ||
runtime: hasSingleRuntimeChunk ? false : runtime, | ||
}).apply(compiler); | ||
compiler.hooks.make.tapAsync(PLUGIN_NAME, (compilation, callback) => { | ||
@@ -166,3 +171,3 @@ const dep = new ContainerEntryDependency_1.default(name, | ||
dep, { | ||
name: name ? name + '_partial' : undefined, // give unique name name | ||
name: 'federation-runtime', // merge container into federation entrypoint added to compilation | ||
runtime: undefined, | ||
@@ -169,0 +174,0 @@ library, |
@@ -1,14 +0,29 @@ | ||
import type { Compiler } from 'webpack'; | ||
import { containerReferencePlugin } from '@module-federation/sdk'; | ||
export = ContainerReferencePlugin; | ||
declare class ContainerReferencePlugin { | ||
private _remoteType; | ||
private _remotes; | ||
constructor(options: containerReferencePlugin.ContainerReferencePluginOptions); | ||
/** | ||
* Apply the plugin | ||
* @param {Compiler} compiler the compiler instance | ||
* @returns {void} | ||
*/ | ||
apply(compiler: Compiler): void; | ||
/** | ||
* @param {ContainerReferencePluginOptions} options options | ||
*/ | ||
constructor(options: ContainerReferencePluginOptions); | ||
_remoteType: import('../../declarations/plugins/container/ContainerReferencePlugin').ExternalsType; | ||
_remotes: [ | ||
string, | ||
{ | ||
external: string[]; | ||
shareScope: string; | ||
}, | ||
][]; | ||
/** | ||
* Apply the plugin | ||
* @param {Compiler} compiler the compiler instance | ||
* @returns {void} | ||
*/ | ||
apply(compiler: Compiler): void; | ||
} | ||
export default ContainerReferencePlugin; | ||
declare namespace ContainerReferencePlugin { | ||
export { ContainerReferencePluginOptions, RemotesConfig, Compiler }; | ||
} | ||
type Compiler = import('webpack/lib/Compiler'); | ||
type ContainerReferencePluginOptions = | ||
import('../../declarations/plugins/container/ContainerReferencePlugin').ContainerReferencePluginOptions; | ||
type RemotesConfig = | ||
import('../../declarations/plugins/container/ContainerReferencePlugin').RemotesConfig; |
@@ -1,2 +0,2 @@ | ||
import type { Compiler, WebpackPluginInstance } from 'webpack'; | ||
import type { Compiler, Compilation, Chunk, WebpackPluginInstance } from 'webpack'; | ||
/** | ||
@@ -6,8 +6,7 @@ * This class is used to hoist container references in the code. | ||
*/ | ||
export declare class HoistContainerReferences implements WebpackPluginInstance { | ||
export declare class HoistContainerReferencesPlugin implements WebpackPluginInstance { | ||
integrateChunks(chunkA: Chunk, chunkB: Chunk, compilation: Compilation): void; | ||
apply(compiler: Compiler): void; | ||
private chunkContainsContainerEntryModule; | ||
private hoistModulesInChunk; | ||
private getRuntimeChunks; | ||
} | ||
export default HoistContainerReferences; | ||
export default HoistContainerReferencesPlugin; |
@@ -6,4 +6,6 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.HoistContainerReferences = void 0; | ||
exports.HoistContainerReferencesPlugin = void 0; | ||
const normalize_webpack_path_1 = require("@module-federation/sdk/normalize-webpack-path"); | ||
const ContainerEntryModule_1 = __importDefault(require("./ContainerEntryModule")); | ||
const runtime = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack/lib/util/runtime')); | ||
/** | ||
@@ -13,43 +15,118 @@ * This class is used to hoist container references in the code. | ||
*/ | ||
class HoistContainerReferences { | ||
class HoistContainerReferencesPlugin { | ||
integrateChunks(chunkA, chunkB, compilation) { | ||
const { chunkGraph, compiler } = compilation; | ||
// do not sort chunk by smallest name, this will cause non-deterministic chunk integration | ||
// if (chunkA.name && chunkB.name) { | ||
// if ( | ||
// chunkGraph.getNumberOfEntryModules(chunkA) > 0 === | ||
// chunkGraph.getNumberOfEntryModules(chunkB) > 0 | ||
// ) { | ||
// // When both chunks have entry modules or none have one, use | ||
// // shortest name | ||
// if (chunkA.name.length !== chunkB.name.length) { | ||
// chunkA.name = | ||
// chunkA.name.length < chunkB.name.length ? chunkA.name : chunkB.name; | ||
// } else { | ||
// chunkA.name = chunkA.name < chunkB.name ? chunkA.name : chunkB.name; | ||
// } | ||
// } else if (chunkGraph.getNumberOfEntryModules(chunkB) > 0) { | ||
// // Pick the name of the chunk with the entry module | ||
// chunkA.name = chunkB.name; | ||
// } | ||
// } else if (chunkB.name) { | ||
// chunkA.name = chunkB.name; | ||
// } | ||
// | ||
// // Merge id name hints | ||
for (const hint of chunkB.idNameHints) { | ||
chunkA.idNameHints.add(hint); | ||
} | ||
// Merge runtime | ||
if (chunkA.name === chunkA.runtime) { | ||
//@ts-ignore | ||
chunkA.runtime = runtime.mergeRuntime(chunkA.runtime, chunkB.runtime); | ||
} | ||
// getChunkModules is used here to create a clone, because disconnectChunkAndModule modifies | ||
for (const module of chunkGraph.getChunkModules(chunkB)) { | ||
// dont disconnect as module may need to be copied into multiple chunks | ||
// chunkGraph.disconnectChunkAndModule(chunkB, module); | ||
chunkGraph.connectChunkAndModule(chunkA, module); | ||
} | ||
for (const [module, chunkGroup] of Array.from(chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunkB))) { | ||
// dont disconnect as module may need to be copied into multiple chunks | ||
// chunkGraph.disconnectChunkAndEntryModule(chunkB, module); | ||
//connect as normal module not entry module to preserve existing entrypoint modules | ||
chunkGraph.connectChunkAndModule(chunkA, module); | ||
// chunkGraph.connectChunkAndEntryModule(chunkA, module,chunkGroup); | ||
} | ||
for (const chunkGroup of chunkB.groupsIterable) { | ||
chunkGroup.replaceChunk(chunkB, chunkA); | ||
chunkA.addGroup(chunkGroup); | ||
chunkB.removeGroup(chunkGroup); | ||
} | ||
compiler.webpack.ChunkGraph.clearChunkGraphForChunk(chunkB); | ||
} | ||
apply(compiler) { | ||
compiler.hooks.thisCompilation.tap('HoistContainerReferences', (compilation) => { | ||
compilation.hooks.afterOptimizeChunks.tap('HoistContainerReferences', (chunks) => { | ||
compiler.hooks.compilation.tap('HoistContainerReferencesPlugin', (compilation) => { | ||
compilation.hooks.afterOptimizeChunks.tap({ | ||
name: 'HoistContainerReferencesPlugin', | ||
stage: 10, // advanced stage chunk optimization | ||
}, (chunks) => { | ||
const { chunkGraph } = compilation; | ||
const federationRuntimeChunk = compilation.namedChunks.get('federation-runtime'); | ||
const federationRuntimePlugins = compilation.namedChunks.get('mfp-runtime-plugins'); | ||
if (!federationRuntimeChunk) | ||
return; | ||
// For each chunk that has a runtime, merge the federation-runtime chunk into it | ||
for (const chunk of chunks) { | ||
if (this.chunkContainsContainerEntryModule(chunk, compilation)) { | ||
this.hoistModulesInChunk(chunk, compilation); | ||
if (chunk.hasRuntime() && | ||
chunk !== federationRuntimeChunk && | ||
chunk !== federationRuntimePlugins) { | ||
// Do not re-integrate chunks with containers in them. Like remoteEntry - this will destroy entry module | ||
if (this.chunkContainsContainerEntryModule(chunk, compilation)) | ||
continue; | ||
this.integrateChunks(chunk, federationRuntimeChunk, compilation); | ||
if (federationRuntimePlugins && | ||
chunk !== federationRuntimePlugins) { | ||
this.integrateChunks(chunk, federationRuntimePlugins, compilation); | ||
} | ||
} | ||
} | ||
for (const module of chunkGraph.getChunkModules(federationRuntimeChunk)) { | ||
chunkGraph.disconnectChunkAndModule(federationRuntimeChunk, module); | ||
} | ||
if (!federationRuntimePlugins) | ||
return; | ||
for (const module of chunkGraph.getChunkModules(federationRuntimePlugins)) { | ||
chunkGraph.disconnectChunkAndModule(federationRuntimePlugins, module); | ||
} | ||
}); | ||
compilation.hooks.beforeChunkAssets.tap('HoistContainerReferencesPlugin', () => { | ||
// the federation-runtime chunk is integrated into multiple other runtime chunks, like main, or runtime.js | ||
// because this entrypoint is integrated using chunk group updates - this chunk cannot be emitted without causing multiple writes to same runtime | ||
// the federation-runtime serves no output process, it is used as a reference to hoist federation runtime once into all runtime chunks for eager consumption | ||
// this plugin serves | ||
const federationRuntimeChunk = compilation.namedChunks.get('federation-runtime'); | ||
const federationRuntimePluginsChunk = compilation.namedChunks.get('mfp-runtime-plugins'); | ||
if (federationRuntimeChunk) | ||
compilation.chunks.delete(federationRuntimeChunk); | ||
if (federationRuntimePluginsChunk) | ||
compilation.chunks.delete(federationRuntimePluginsChunk); | ||
}); | ||
}); | ||
} | ||
chunkContainsContainerEntryModule(chunk, compilation) { | ||
let hasContainerEntryModule = false; | ||
for (const module of compilation.chunkGraph.getChunkModulesIterable(chunk)) { | ||
if (module instanceof ContainerEntryModule_1.default) { | ||
return true; | ||
hasContainerEntryModule = true; | ||
break; | ||
} | ||
} | ||
return false; | ||
return hasContainerEntryModule; | ||
} | ||
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; | ||
} | ||
} | ||
exports.HoistContainerReferences = HoistContainerReferences; | ||
exports.default = HoistContainerReferences; | ||
exports.HoistContainerReferencesPlugin = HoistContainerReferencesPlugin; | ||
exports.default = HoistContainerReferencesPlugin; | ||
//# sourceMappingURL=HoistContainerReferencesPlugin.js.map |
@@ -1,16 +0,23 @@ | ||
import type { Compiler, WebpackPluginInstance } from 'webpack'; | ||
import type { moduleFederationPlugin } from '@module-federation/sdk'; | ||
declare class ModuleFederationPlugin implements WebpackPluginInstance { | ||
private _options; | ||
/** | ||
* @param {moduleFederationPlugin.ModuleFederationPluginOptions} options options | ||
*/ | ||
constructor(options: moduleFederationPlugin.ModuleFederationPluginOptions); | ||
/** | ||
* Apply the plugin | ||
* @param {Compiler} compiler the compiler instance | ||
* @returns {void} | ||
*/ | ||
apply(compiler: Compiler): void; | ||
export = ModuleFederationPlugin; | ||
declare class ModuleFederationPlugin { | ||
/** | ||
* @param {ModuleFederationPluginOptions} options options | ||
*/ | ||
constructor(options: any); | ||
name: string; | ||
_options: any; | ||
/** | ||
* Apply the plugin | ||
* @param {Compiler} compiler the compiler instance | ||
* @returns {void} | ||
*/ | ||
apply(compiler: Compiler): void; | ||
} | ||
export default ModuleFederationPlugin; | ||
declare namespace ModuleFederationPlugin { | ||
export { ExternalsType, ModuleFederationPluginOptions, Shared, Compiler }; | ||
} | ||
type Compiler = import('webpack/lib/Compiler'); | ||
type ExternalsType = any; | ||
type ModuleFederationPluginOptions = | ||
import('../../declarations/plugins/container/ModuleFederationPlugin').ModuleFederationPluginOptions; | ||
type Shared = any; |
@@ -14,11 +14,10 @@ /* | ||
const ContainerReferencePlugin_1 = __importDefault(require("./ContainerReferencePlugin")); | ||
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 manifest_1 = require("@module-federation/manifest"); | ||
const managers_1 = require("@module-federation/managers"); | ||
const isValidExternalsType = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack/schemas/plugins/container/ExternalsType.check.js')); | ||
const createSchemaValidation = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack/lib/util/create-schema-validation')); | ||
const validate = createSchemaValidation( | ||
// just use schema to validate | ||
() => false, () => ModuleFederationPlugin_1.default, { | ||
//eslint-disable-next-line | ||
ModuleFederationPlugin_check_1.default, () => ModuleFederationPlugin_1.default, { | ||
name: 'Module Federation Plugin', | ||
@@ -29,3 +28,3 @@ baseDataPath: 'options', | ||
/** | ||
* @param {moduleFederationPlugin.ModuleFederationPluginOptions} options options | ||
* @param {ModuleFederationPluginOptions} options options | ||
*/ | ||
@@ -43,3 +42,2 @@ constructor(options) { | ||
const { _options: options } = this; | ||
// @ts-ignore | ||
new FederationRuntimePlugin_1.default(options).apply(compiler); | ||
@@ -59,7 +57,3 @@ const library = options.library || { type: 'var', name: options.name }; | ||
} | ||
if (options.manifest && useContainerPlugin) { | ||
const containerManager = new managers_1.ContainerManager(); | ||
containerManager.init(options); | ||
options.exposes = containerManager.containerPluginExposesOptions; | ||
} | ||
ContainerPlugin_1.default.patchChunkSplit(compiler, 'federation-runtime'); | ||
if (library && | ||
@@ -81,3 +75,2 @@ !compiler.options.output.enabledLibraryTypes?.includes(library.type)) { | ||
runtimePlugins: options.runtimePlugins, | ||
//@ts-ignore | ||
}).apply(compiler); | ||
@@ -103,9 +96,2 @@ } | ||
}); | ||
if (options.manifest) { | ||
const pkg = require('../../../../package.json'); | ||
new manifest_1.StatsPlugin(options, { | ||
pluginVersion: pkg.version, | ||
bundler: 'webpack', | ||
}).apply(compiler); | ||
} | ||
} | ||
@@ -112,0 +98,0 @@ } |
import type { Compiler } from 'webpack'; | ||
import type { moduleFederationPlugin } from '@module-federation/sdk'; | ||
import type { ModuleFederationPluginOptions } from '../../../declarations/plugins/container/ModuleFederationPlugin'; | ||
declare class FederationRuntimePlugin { | ||
options?: moduleFederationPlugin.ModuleFederationPluginOptions; | ||
options?: ModuleFederationPluginOptions; | ||
entryFilePath: string; | ||
pluginsFilePath: string; | ||
bundlerRuntimePath: string; | ||
constructor(options?: moduleFederationPlugin.ModuleFederationPluginOptions); | ||
static getTemplate(runtimePlugins: string[], bundlerRuntimePath?: string): string; | ||
static getFilePath(containerName: string, runtimePlugins: string[], bundlerRuntimePath?: string): string; | ||
getFilePath(): string; | ||
ensureFile(): void; | ||
constructor(options?: ModuleFederationPluginOptions); | ||
static getTemplate(bundlerRuntimePath: string): string; | ||
static getPluginsTemplate(runtimePlugins: string[]): string; | ||
ensureFiles(): void; | ||
writeFile(filePath: string, content: string): void; | ||
prependEntry(compiler: Compiler): void; | ||
@@ -13,0 +14,0 @@ injectRuntime(compiler: Compiler): void; |
@@ -8,2 +8,3 @@ "use strict"; | ||
const FederationRuntimeModule_1 = __importDefault(require("./FederationRuntimeModule")); | ||
const FederationInitModule_1 = __importDefault(require("./FederationInitModule")); | ||
const utils_1 = require("./utils"); | ||
@@ -13,2 +14,3 @@ const fs_1 = __importDefault(require("fs")); | ||
const constant_1 = require("../constant"); | ||
const HoistContainerReferencesPlugin_1 = __importDefault(require("../HoistContainerReferencesPlugin")); | ||
const { RuntimeGlobals, Template } = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack')); | ||
@@ -26,11 +28,31 @@ const { mkdirpSync } = require((0, normalize_webpack_path_1.normalizeWebpackPath)('webpack/lib/util/fs')); | ||
constructor(options) { | ||
this.options = { ...options }; | ||
this.options = options; | ||
this.entryFilePath = ''; | ||
this.pluginsFilePath = ''; // Initialize plugins file path | ||
this.bundlerRuntimePath = BundlerRuntimePath; | ||
} | ||
static getTemplate(runtimePlugins, bundlerRuntimePath) { | ||
static getTemplate(bundlerRuntimePath) { | ||
// internal runtime plugin | ||
const normalizedBundlerRuntimePath = (0, utils_1.normalizeToPosixPath)(bundlerRuntimePath || BundlerRuntimePath); | ||
return Template.asString([ | ||
`import federation from '${normalizedBundlerRuntimePath}';`, | ||
`${federationGlobal} = {...federation,...${federationGlobal}};`, | ||
`if(!${federationGlobal}.instance){`, | ||
Template.indent([ | ||
`${federationGlobal}.instance = ${federationGlobal}.runtime.init(${federationGlobal}.initOptions);`, | ||
`if(${federationGlobal}.attachShareScopeMap){`, | ||
Template.indent([ | ||
`${federationGlobal}.attachShareScopeMap(${RuntimeGlobals.require})`, | ||
]), | ||
'}', | ||
`if(${federationGlobal}.installInitialConsumes){`, | ||
Template.indent([`${federationGlobal}.installInitialConsumes()`]), | ||
'}', | ||
]), | ||
'}', | ||
]); | ||
} | ||
static getPluginsTemplate(runtimePlugins) { | ||
let runtimePluginTemplates = ''; | ||
const runtimePLuginNames = []; | ||
const runtimePluginNames = []; | ||
if (Array.isArray(runtimePlugins)) { | ||
@@ -43,27 +65,19 @@ runtimePlugins.forEach((runtimePlugin, index) => { | ||
runtimePluginTemplates += `import ${runtimePluginName} from '${runtimePluginPath}';\n`; | ||
runtimePLuginNames.push(runtimePluginName); | ||
runtimePluginNames.push(runtimePluginName); | ||
}); | ||
} | ||
return Template.asString([ | ||
`import federation from '${normalizedBundlerRuntimePath}';`, | ||
runtimePluginTemplates, | ||
`${federationGlobal} = {...federation,...${federationGlobal}};`, | ||
`if(!${federationGlobal}.instance){`, | ||
`if(${federationGlobal}.instance){`, | ||
Template.indent([ | ||
runtimePLuginNames.length | ||
runtimePluginNames.length | ||
? Template.asString([ | ||
`${federationGlobal}.initOptions.plugins = ([`, | ||
Template.indent(runtimePLuginNames.map((item) => `${item}(),`)), | ||
'])', | ||
`${federationGlobal}.initOptions.plugins = ${federationGlobal}.initOptions.plugins ? ${federationGlobal}.initOptions.plugins.concat([`, | ||
Template.indent(runtimePluginNames.map((item) => `${item}(),`)), | ||
']) : [', | ||
Template.indent(runtimePluginNames.map((item) => `${item}(),`)), | ||
'];', | ||
]) | ||
: '', | ||
`${federationGlobal}.instance = ${federationGlobal}.runtime.init(${federationGlobal}.initOptions);`, | ||
`if(${federationGlobal}.attachShareScopeMap){`, | ||
Template.indent([ | ||
`${federationGlobal}.attachShareScopeMap(${RuntimeGlobals.require})`, | ||
]), | ||
'}', | ||
`if(${federationGlobal}.installInitialConsumes){`, | ||
Template.indent([`${federationGlobal}.installInitialConsumes()`]), | ||
'}', | ||
`${federationGlobal}.runtime.init(${federationGlobal}.initOptions);`, //init again with plugins attached. | ||
]), | ||
@@ -73,21 +87,16 @@ '}', | ||
} | ||
static getFilePath(containerName, runtimePlugins, bundlerRuntimePath) { | ||
const hash = (0, utils_1.createHash)(`${containerName} ${FederationRuntimePlugin.getTemplate(runtimePlugins, bundlerRuntimePath)}`); | ||
return path_1.default.join(constant_1.TEMP_DIR, `entry.${hash}.js`); | ||
} | ||
getFilePath() { | ||
if (this.entryFilePath) { | ||
return this.entryFilePath; | ||
} | ||
ensureFiles() { | ||
if (!this.options) { | ||
return ''; | ||
return; | ||
} | ||
this.entryFilePath = FederationRuntimePlugin.getFilePath(this.options.name, this.options.runtimePlugins, this.bundlerRuntimePath); | ||
return this.entryFilePath; | ||
const federationTemplate = FederationRuntimePlugin.getTemplate(this.bundlerRuntimePath); | ||
const pluginsTemplate = FederationRuntimePlugin.getPluginsTemplate(this.options.runtimePlugins || []); | ||
const federationHash = (0, utils_1.createHash)(federationTemplate); | ||
const pluginsHash = (0, utils_1.createHash)(pluginsTemplate); | ||
this.entryFilePath = path_1.default.join(constant_1.TEMP_DIR, `federation.${federationHash}.js`); | ||
this.pluginsFilePath = path_1.default.join(constant_1.TEMP_DIR, `plugins.${pluginsHash}.js`); | ||
this.writeFile(this.entryFilePath, federationTemplate); | ||
this.writeFile(this.pluginsFilePath, pluginsTemplate); | ||
} | ||
ensureFile() { | ||
if (!this.options) { | ||
return; | ||
} | ||
const filePath = this.getFilePath(); | ||
writeFile(filePath, content) { | ||
try { | ||
@@ -97,22 +106,17 @@ fs_1.default.readFileSync(filePath); | ||
catch (err) { | ||
mkdirpSync(fs_1.default, constant_1.TEMP_DIR); | ||
fs_1.default.writeFileSync(filePath, FederationRuntimePlugin.getTemplate(this.options.runtimePlugins, this.bundlerRuntimePath)); | ||
mkdirpSync(fs_1.default, path_1.default.dirname(filePath)); | ||
fs_1.default.writeFileSync(filePath, content); | ||
} | ||
} | ||
prependEntry(compiler) { | ||
this.ensureFile(); | ||
const entryFilePath = this.getFilePath(); | ||
this.ensureFiles(); | ||
(0, utils_1.modifyEntry)({ | ||
compiler, | ||
prependEntry: (entry) => { | ||
Object.keys(entry).forEach((entryName) => { | ||
const entryItem = entry[entryName]; | ||
if (!entryItem.import) { | ||
// TODO: maybe set this variable as constant is better https://github.com/webpack/webpack/blob/main/lib/config/defaults.js#L176 | ||
entryItem.import = ['./src']; | ||
} | ||
if (!entryItem.import.includes(entryFilePath)) { | ||
entryItem.import.unshift(entryFilePath); | ||
} | ||
}); | ||
entry['mfp-runtime-plugins'] = { | ||
import: [this.pluginsFilePath], | ||
}; | ||
entry['federation-runtime'] = { | ||
import: [this.entryFilePath], | ||
}; | ||
}, | ||
@@ -129,2 +133,10 @@ }); | ||
compiler.hooks.thisCompilation.tap(this.constructor.name, (compilation, { normalModuleFactory }) => { | ||
let chunksRuntimePluginsDependsOn = undefined; | ||
compilation.hooks.afterOptimizeChunks.tap(this.constructor.name, (chunk) => { | ||
const runtimePluginEntry = compilation.namedChunks.get('mfp-runtime-plugins'); | ||
if (runtimePluginEntry) { | ||
chunksRuntimePluginsDependsOn = | ||
runtimePluginEntry.getAllInitialChunks(); | ||
} | ||
}); | ||
compilation.hooks.additionalTreeRuntimeRequirements.tap(this.constructor.name, (chunk, runtimeRequirements) => { | ||
@@ -139,2 +151,3 @@ if (runtimeRequirements.has(federationGlobal)) { | ||
compilation.addRuntimeModule(chunk, new FederationRuntimeModule_1.default(runtimeRequirements, name, initOptionsWithoutShared)); | ||
compilation.addRuntimeModule(chunk, new FederationInitModule_1.default(name, this.entryFilePath, chunksRuntimePluginsDependsOn)); | ||
}); | ||
@@ -205,2 +218,3 @@ }); | ||
this.setRuntimeAlias(compiler); | ||
new HoistContainerReferencesPlugin_1.default().apply(compiler); | ||
} | ||
@@ -207,0 +221,0 @@ } |
import type webpack from 'webpack'; | ||
import type RuntimeGlobals from 'webpack/lib/RuntimeGlobals'; | ||
import type { moduleFederationPlugin } from '@module-federation/sdk'; | ||
import type { ModuleFederationPluginOptions } from '../../../declarations/plugins/container/ModuleFederationPlugin'; | ||
import { NormalizedRuntimeInitOptionsWithOutShared } from '../../../types/runtime'; | ||
@@ -12,3 +12,3 @@ type EntryStaticNormalized = Awaited<ReturnType<Extract<webpack.WebpackOptionsNormalized['entry'], () => any>>>; | ||
export declare function getFederationGlobalScope(runtimeGlobals: typeof RuntimeGlobals): string; | ||
export declare function normalizeRuntimeInitOptionsWithOutShared(options: moduleFederationPlugin.ModuleFederationPluginOptions): NormalizedRuntimeInitOptionsWithOutShared; | ||
export declare function normalizeRuntimeInitOptionsWithOutShared(options: ModuleFederationPluginOptions): NormalizedRuntimeInitOptionsWithOutShared; | ||
export declare function modifyEntry(options: ModifyEntryOptions): void; | ||
@@ -15,0 +15,0 @@ export declare function createHash(contents: string): string; |
@@ -7,4 +7,4 @@ /* | ||
declare const check: ( | ||
options: import('@module-federation/sdk').moduleFederationPlugin.ModuleFederationPluginOptions, | ||
options: import('../../../declarations/plugins/container/ModuleFederationPlugin').ModuleFederationPluginOptions, | ||
) => boolean; | ||
export = check; |
@@ -391,16 +391,2 @@ declare const _default: { | ||
}; | ||
Manifest: { | ||
description: string; | ||
type: string; | ||
properties: { | ||
filePath: { | ||
description: string; | ||
type: string; | ||
}; | ||
disableAssetsAnalyze: { | ||
description: string; | ||
type: string; | ||
}; | ||
}; | ||
}; | ||
}; | ||
@@ -451,12 +437,2 @@ title: string; | ||
}; | ||
manifest: { | ||
description: string; | ||
anyOf: ({ | ||
$ref: string; | ||
type?: undefined; | ||
} | { | ||
type: string; | ||
$ref?: undefined; | ||
})[]; | ||
}; | ||
shareScope: { | ||
@@ -463,0 +439,0 @@ description: string; |
@@ -481,16 +481,2 @@ "use strict"; | ||
}, | ||
Manifest: { | ||
description: 'Used to config manifest.', | ||
type: 'object', | ||
properties: { | ||
filePath: { | ||
description: 'The file path of the vmok manifest.', | ||
type: 'string', | ||
}, | ||
disableAssetsAnalyze: { | ||
description: 'Used to disable assets analyze in dev. If the value is set to true, manifest will neither have shared and exposes fields nor have remotes detail. Generally, it will be set to true in dev if the project is a pure consumer.', | ||
type: 'boolean', | ||
}, | ||
}, | ||
}, | ||
}, | ||
@@ -543,13 +529,2 @@ title: 'ModuleFederationPluginOptions', | ||
}, | ||
manifest: { | ||
description: 'Used to config manifest.', | ||
anyOf: [ | ||
{ | ||
$ref: '#/definitions/Manifest', | ||
}, | ||
{ | ||
type: 'boolean', | ||
}, | ||
], | ||
}, | ||
shareScope: { | ||
@@ -556,0 +531,0 @@ description: "Share scope name used for all shared modules (defaults to 'default').", |
import type { WebpackPluginInstance, Compiler } from 'webpack'; | ||
import type { containerPlugin } from '@module-federation/sdk'; | ||
import type { ContainerPluginOptions } from '../declarations/plugins/container/ContainerPlugin'; | ||
export default class ContainerPlugin implements WebpackPluginInstance { | ||
private _options; | ||
name: string; | ||
constructor(options: containerPlugin.ContainerPluginOptions); | ||
constructor(options: ContainerPluginOptions); | ||
apply(compiler: Compiler): void; | ||
} |
import type { WebpackPluginInstance, Compiler } from 'webpack'; | ||
import type { containerReferencePlugin } from '@module-federation/sdk'; | ||
import type { ContainerReferencePluginOptions } from '../declarations/plugins/container/ContainerReferencePlugin'; | ||
export default class ContainerReferencePlugin implements WebpackPluginInstance { | ||
private _options; | ||
name: string; | ||
constructor(options: containerReferencePlugin.ContainerReferencePluginOptions); | ||
constructor(options: ContainerReferencePluginOptions); | ||
apply(compiler: Compiler): void; | ||
} |
import type { WebpackPluginInstance, Compiler } from 'webpack'; | ||
import type { moduleFederationPlugin } from '@module-federation/sdk'; | ||
import type { ModuleFederationPluginOptions } from '../lib/container/ModuleFederationPluginTypes'; | ||
export default class FederationRuntimePlugin implements WebpackPluginInstance { | ||
@@ -7,4 +7,4 @@ private _options?; | ||
entryFilePath: string; | ||
constructor(options?: moduleFederationPlugin.ModuleFederationPluginOptions); | ||
constructor(options?: ModuleFederationPluginOptions); | ||
apply(compiler: Compiler): void; | ||
} |
import type { WebpackPluginInstance, Compiler } from 'webpack'; | ||
import type { moduleFederationPlugin } from '@module-federation/sdk'; | ||
import type { ModuleFederationPluginOptions } from '../lib/container/ModuleFederationPluginTypes'; | ||
export default class ModuleFederationPlugin implements WebpackPluginInstance { | ||
private _options; | ||
name: string; | ||
constructor(options: moduleFederationPlugin.ModuleFederationPluginOptions); | ||
constructor(options: ModuleFederationPluginOptions); | ||
apply(compiler: Compiler): void; | ||
} |
{ | ||
"name": "@module-federation/enhanced", | ||
"version": "0.0.0-next-20240227135200", | ||
"version": "0.0.0-next-20240228024304", | ||
"main": "./dist/src/index.js", | ||
@@ -31,11 +31,9 @@ "types": "./dist/src/index.d.ts", | ||
"devDependencies": { | ||
"@module-federation/webpack-bundler-runtime": "0.0.0-next-20240227135200" | ||
"@module-federation/webpack-bundler-runtime": "0.0.0-next-20240228024304" | ||
}, | ||
"dependencies": { | ||
"upath": "2.0.1", | ||
"@module-federation/sdk": "0.0.0-next-20240227135200", | ||
"@module-federation/runtime-tools": "0.0.0-next-20240227135200", | ||
"@module-federation/manifest": "0.0.0-next-20240227135200", | ||
"@module-federation/managers": "0.0.0-next-20240227135200" | ||
"@module-federation/sdk": "0.0.0-next-20240228024304", | ||
"@module-federation/runtime-tools": "0.0.0-next-20240228024304" | ||
} | ||
} |
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
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
984434
4
196
17267
75
94
+ Added@module-federation/runtime@0.0.0-next-20240228024304(transitive)
+ Added@module-federation/runtime-tools@0.0.0-next-20240228024304(transitive)
+ Added@module-federation/sdk@0.0.0-next-20240228024304(transitive)
+ Added@module-federation/webpack-bundler-runtime@0.0.0-next-20240228024304(transitive)
- Removed@module-federation/managers@0.0.0-next-20240227135200
- Removed@module-federation/manifest@0.0.0-next-20240227135200
- Removed@module-federation/managers@0.0.0-next-20240227135200(transitive)
- Removed@module-federation/manifest@0.0.0-next-20240227135200(transitive)
- Removed@module-federation/runtime@0.0.0-next-20240227135200(transitive)
- Removed@module-federation/runtime-tools@0.0.0-next-20240227135200(transitive)
- Removed@module-federation/sdk@0.0.0-next-20240227135200(transitive)
- Removed@module-federation/webpack-bundler-runtime@0.0.0-next-20240227135200(transitive)
- Removedansi-styles@4.3.0(transitive)
- Removedat-least-node@1.0.0(transitive)
- Removedchalk@3.0.0(transitive)
- Removedcolor-convert@2.0.1(transitive)
- Removedcolor-name@1.1.4(transitive)
- Removedexpand-tilde@2.0.2(transitive)
- Removedfind-file-up@2.0.1(transitive)
- Removedfind-pkg@2.0.0(transitive)
- Removedfs-extra@9.1.0(transitive)
- Removedglobal-modules@1.0.0(transitive)
- Removedglobal-prefix@1.0.2(transitive)
- Removedhomedir-polyfill@1.0.3(transitive)
- Removedini@1.3.8(transitive)
- Removedis-windows@1.0.2(transitive)
- Removedisexe@2.0.0(transitive)
- Removedjsonfile@6.1.0(transitive)
- Removedparse-passwd@1.0.0(transitive)
- Removedresolve-dir@1.0.1(transitive)
- Removedsupports-color@7.2.0(transitive)
- Removeduniversalify@2.0.1(transitive)
- Removedwhich@1.3.1(transitive)
Updated@module-federation/runtime-tools@0.0.0-next-20240228024304