feat: support custom chunk name in container expose options

Module federation generates async chunks for exposed modules, which by
default named after the internal module id. This change allows users to
assign a custom name so that the file can be statically referenced.
This commit is contained in:
Art Chen 2021-01-28 09:00:05 -08:00
parent 8ce54a045f
commit cd0310f6d6
13 changed files with 71 additions and 3 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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]
);

View File

@ -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
})
)
};

View File

@ -37,6 +37,10 @@
"$ref": "#/definitions/ExposesItems"
}
]
},
"name": {
"description": "Custom chunk name for the exposed module.",
"type": "string"
}
},
"required": ["import"]

View File

@ -49,6 +49,10 @@
"$ref": "#/definitions/ExposesItems"
}
]
},
"name": {
"description": "Custom chunk name for the exposed module.",
"type": "string"
}
},
"required": ["import"]

View File

@ -49,6 +49,10 @@
"$ref": "#/definitions/ExposesItems"
}
]
},
"name": {
"description": "Custom chunk name for the exposed module.",
"type": "string"
}
},
"required": ["import"]

View File

@ -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'

View File

@ -0,0 +1 @@
export default function bootstrap() {}

View File

@ -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"
}
}
})
]
};

5
types.d.ts vendored
View File

@ -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;
}
/**