diff --git a/declarations/_container.d.ts b/declarations/_container.d.ts index 1399f934c..912089e9f 100644 --- a/declarations/_container.d.ts +++ b/declarations/_container.d.ts @@ -49,6 +49,10 @@ export interface ExposesConfig { * Request to a module that should be exposed by this container. */ import: ExposesItem | ExposesItems; + /** + * Custom chunk name for the exposed module. + */ + name?: string; } /** * Container locations from which modules should be resolved and loaded at runtime. Property names are used as request scopes. diff --git a/declarations/plugins/container/ContainerPlugin.d.ts b/declarations/plugins/container/ContainerPlugin.d.ts index c090aeecc..3c47757ba 100644 --- a/declarations/plugins/container/ContainerPlugin.d.ts +++ b/declarations/plugins/container/ContainerPlugin.d.ts @@ -96,6 +96,10 @@ export interface ExposesConfig { * Request to a module that should be exposed by this container. */ import: ExposesItem | ExposesItems; + /** + * Custom chunk name for the exposed module. + */ + name?: string; } /** * Options for library. diff --git a/declarations/plugins/container/ModuleFederationPlugin.d.ts b/declarations/plugins/container/ModuleFederationPlugin.d.ts index eca4e34d3..40c9e4f9a 100644 --- a/declarations/plugins/container/ModuleFederationPlugin.d.ts +++ b/declarations/plugins/container/ModuleFederationPlugin.d.ts @@ -151,6 +151,10 @@ export interface ExposesConfig { * Request to a module that should be exposed by this container. */ import: ExposesItem | ExposesItems; + /** + * Custom chunk name for the exposed module. + */ + name?: string; } /** * Options for library. diff --git a/lib/container/ContainerEntryModule.js b/lib/container/ContainerEntryModule.js index 90cf5fd14..4cb7516d9 100644 --- a/lib/container/ContainerEntryModule.js +++ b/lib/container/ContainerEntryModule.js @@ -31,6 +31,7 @@ const ContainerExposedDependency = require("./ContainerExposedDependency"); /** * @typedef {Object} ExposeOptions * @property {string[]} import requests to exposed modules (last one is exported) + * @property {string} name custom chunk name for the exposed module */ const SOURCE_TYPES = new Set(["javascript"]); @@ -107,7 +108,9 @@ class ContainerEntryModule extends Module { for (const [name, options] of this._exposes) { const block = new AsyncDependenciesBlock( - undefined, + { + name: options.name + }, { name }, options.import[options.import.length - 1] ); diff --git a/lib/container/ContainerPlugin.js b/lib/container/ContainerPlugin.js index 8368613e4..a9491f032 100644 --- a/lib/container/ContainerPlugin.js +++ b/lib/container/ContainerPlugin.js @@ -35,10 +35,12 @@ class ContainerPlugin { exposes: parseOptions( options.exposes, item => ({ - import: Array.isArray(item) ? item : [item] + import: Array.isArray(item) ? item : [item], + name: undefined }), item => ({ - import: Array.isArray(item.import) ? item.import : [item.import] + import: Array.isArray(item.import) ? item.import : [item.import], + name: item.name || undefined }) ) }; diff --git a/schemas/_container.json b/schemas/_container.json index 3530888a5..e333f1db0 100644 --- a/schemas/_container.json +++ b/schemas/_container.json @@ -37,6 +37,10 @@ "$ref": "#/definitions/ExposesItems" } ] + }, + "name": { + "description": "Custom chunk name for the exposed module.", + "type": "string" } }, "required": ["import"] diff --git a/schemas/plugins/container/ContainerPlugin.json b/schemas/plugins/container/ContainerPlugin.json index 5e83c7d9b..6b9c6ec28 100644 --- a/schemas/plugins/container/ContainerPlugin.json +++ b/schemas/plugins/container/ContainerPlugin.json @@ -49,6 +49,10 @@ "$ref": "#/definitions/ExposesItems" } ] + }, + "name": { + "description": "Custom chunk name for the exposed module.", + "type": "string" } }, "required": ["import"] diff --git a/schemas/plugins/container/ModuleFederationPlugin.json b/schemas/plugins/container/ModuleFederationPlugin.json index 07de23823..16aa02baf 100644 --- a/schemas/plugins/container/ModuleFederationPlugin.json +++ b/schemas/plugins/container/ModuleFederationPlugin.json @@ -49,6 +49,10 @@ "$ref": "#/definitions/ExposesItems" } ] + }, + "name": { + "description": "Custom chunk name for the exposed module.", + "type": "string" } }, "required": ["import"] diff --git a/test/__snapshots__/StatsTestCases.test.js.snap b/test/__snapshots__/StatsTestCases.test.js.snap index 4c36175d2..648a04e9c 100644 --- a/test/__snapshots__/StatsTestCases.test.js.snap +++ b/test/__snapshots__/StatsTestCases.test.js.snap @@ -1271,6 +1271,18 @@ chunk (runtime: e1, e2, e3) async2.js (async2) 135 bytes [rendered] webpack x.x.x compiled successfully" `; +exports[`StatsTestCases should print correct stats for module-federation-custom-exposed-module-name 1`] = ` +"asset container_bundle.js 12 KiB [emitted] (name: container) +asset custom-entry_bundle.js 412 bytes [emitted] (name: custom-entry) +asset main_bundle.js 54 bytes [emitted] (name: main) +runtime modules 6.59 KiB 9 modules +built modules 82 bytes [built] + ./index.js 1 bytes [built] [code generated] + container entry 42 bytes [built] [code generated] + ./entry.js 39 bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + exports[`StatsTestCases should print correct stats for module-not-found-error 1`] = ` "ERROR in ./index.js 1:0-17 Module not found: Error: Can't resolve 'buffer' in 'Xdir/module-not-found-error' diff --git a/test/statsCases/module-federation-custom-exposed-module-name/entry.js b/test/statsCases/module-federation-custom-exposed-module-name/entry.js new file mode 100644 index 000000000..5e8c8f3bf --- /dev/null +++ b/test/statsCases/module-federation-custom-exposed-module-name/entry.js @@ -0,0 +1 @@ +export default function bootstrap() {} diff --git a/test/statsCases/module-federation-custom-exposed-module-name/index.js b/test/statsCases/module-federation-custom-exposed-module-name/index.js new file mode 100644 index 000000000..e69de29bb diff --git a/test/statsCases/module-federation-custom-exposed-module-name/webpack.config.js b/test/statsCases/module-federation-custom-exposed-module-name/webpack.config.js new file mode 100644 index 000000000..ac57c47b9 --- /dev/null +++ b/test/statsCases/module-federation-custom-exposed-module-name/webpack.config.js @@ -0,0 +1,21 @@ +const { ModuleFederationPlugin } = require("../../../").container; + +/** @type {import("../../../").Configuration} */ +module.exports = { + mode: "production", + entry: "./index.js", + output: { + filename: "[name]_bundle.js" + }, + plugins: [ + new ModuleFederationPlugin({ + name: "container", + exposes: { + "./entry": { + import: "./entry", + name: "custom-entry" + } + } + }) + ] +}; diff --git a/types.d.ts b/types.d.ts index a4f3deb7a..69c827a37 100644 --- a/types.d.ts +++ b/types.d.ts @@ -3251,6 +3251,11 @@ declare interface ExposesConfig { * Request to a module that should be exposed by this container. */ import: string | string[]; + + /** + * Custom chunk name for the exposed module. + */ + name?: string; } /**