diff --git a/lib/container/ContainerEntryModule.js b/lib/container/ContainerEntryModule.js index 7b2ec9ab4..0da159096 100644 --- a/lib/container/ContainerEntryModule.js +++ b/lib/container/ContainerEntryModule.js @@ -27,10 +27,6 @@ const ContainerExposedDependency = require("./ContainerExposedDependency"); /** @typedef {import("./ContainerEntryDependency")} ContainerEntryDependency */ const SOURCE_TYPES = new Set(["javascript"]); -const RUNTIME_REQUIREMENTS = new Set([ - RuntimeGlobals.definePropertyGetters, - RuntimeGlobals.exports -]); module.exports = class ContainerEntryModule extends Module { /** @@ -117,7 +113,10 @@ module.exports = class ContainerEntryModule extends Module { */ codeGeneration({ moduleGraph, chunkGraph, runtimeTemplate }) { const sources = new Map(); - const runtimeRequirements = RUNTIME_REQUIREMENTS; + const runtimeRequirements = new Set([ + RuntimeGlobals.definePropertyGetters, + RuntimeGlobals.exports + ]); const getters = []; for (const block of this.blocks) { @@ -172,10 +171,15 @@ module.exports = class ContainerEntryModule extends Module { ["module"], `return typeof __MODULE_MAP__[module] ==='function' ? __MODULE_MAP__[module].apply(null) : Promise.reject(new Error('Module ' + module + ' does not exist.'))` )};`, + `var __OVERRIDE__ = ${runtimeTemplate.basicFunction( + "override", + `Object.assign(${RuntimeGlobals.overrides}, override);` + )}`, "", `${RuntimeGlobals.definePropertyGetters}(exports, {`, Template.indent([ - `get: ${runtimeTemplate.returningFunction("__GET_MODULE__")}` + `get: ${runtimeTemplate.returningFunction("__GET_MODULE__")},`, + `override: ${runtimeTemplate.returningFunction("__OVERRIDE__")}` ]), "});" ]) diff --git a/lib/container/ContainerPlugin.js b/lib/container/ContainerPlugin.js index 7876bd430..bad0ae062 100644 --- a/lib/container/ContainerPlugin.js +++ b/lib/container/ContainerPlugin.js @@ -10,6 +10,7 @@ const schema = require("../../schemas/plugins/ContainerPlugin.json"); const ContainerEntryDependency = require("./ContainerEntryDependency"); const ContainerEntryModuleFactory = require("./ContainerEntryModuleFactory"); const ContainerExposedDependency = require("./ContainerExposedDependency"); +const OverridablesPlugin = require("./OverridablesPlugin"); const parseOptions = require("./parseOptions"); /** @typedef {import("../../declarations/plugins/ContainerPlugin").ContainerPluginOptions} ContainerPluginOptions */ @@ -25,7 +26,7 @@ module.exports = class ContainerPlugin { validateOptions(schema, options, { name: PLUGIN_NAME }); this.options = { - overridables: parseOptions(options.overridables), + overridables: options.overridables, name: options.name, library: options.library || { type: "var", @@ -41,10 +42,12 @@ module.exports = class ContainerPlugin { * @returns {void} */ apply(compiler) { - const { name, exposes, filename, library } = this.options; + const { name, exposes, filename, library, overridables } = this.options; compiler.options.output.enabledLibraryTypes.push(library.type); + new OverridablesPlugin(overridables).apply(compiler); + compiler.hooks.make.tapAsync(PLUGIN_NAME, (compilation, callback) => { const dep = new ContainerEntryDependency(exposes); dep.loc = { name }; diff --git a/lib/container/ContainerReferencePlugin.js b/lib/container/ContainerReferencePlugin.js index beec824af..01600de61 100644 --- a/lib/container/ContainerReferencePlugin.js +++ b/lib/container/ContainerReferencePlugin.js @@ -75,16 +75,14 @@ module.exports = class ContainerReferencePlugin { } ); - compilation.hooks.additionalTreeRuntimeRequirements.tap( - "OverridablesPlugin", - (chunk, set) => { + compilation.hooks.runtimeRequirementInTree + .for(RuntimeGlobals.ensureChunkHandlers) + .tap("OverridablesPlugin", (chunk, set) => { set.add(RuntimeGlobals.module); set.add(RuntimeGlobals.moduleFactories); set.add(RuntimeGlobals.hasOwnProperty); - set.add(RuntimeGlobals.ensureChunkHandlers); compilation.addRuntimeModule(chunk, new RemoteRuntimeModule()); - } - ); + }); } ); } diff --git a/lib/container/OverridablesPlugin.js b/lib/container/OverridablesPlugin.js index 592778e71..d408c1931 100644 --- a/lib/container/OverridablesPlugin.js +++ b/lib/container/OverridablesPlugin.js @@ -72,19 +72,17 @@ class OverridablesPlugin { if (key !== undefined) return new OverridableModule(module, key); } ); - compilation.hooks.additionalTreeRuntimeRequirements.tap( - "OverridablesPlugin", - (chunk, set) => { + compilation.hooks.runtimeRequirementInTree + .for(RuntimeGlobals.ensureChunkHandlers) + .tap("OverridablesPlugin", (chunk, set) => { set.add(RuntimeGlobals.module); set.add(RuntimeGlobals.moduleFactories); set.add(RuntimeGlobals.hasOwnProperty); - set.add(RuntimeGlobals.ensureChunkHandlers); compilation.addRuntimeModule( chunk, new OverridablesRuntimeModule() ); - } - ); + }); } ); } diff --git a/test/configCases/container/container-entry-overridables/index.js b/test/configCases/container/container-entry-overridables/index.js new file mode 100644 index 000000000..928730774 --- /dev/null +++ b/test/configCases/container/container-entry-overridables/index.js @@ -0,0 +1,23 @@ +it("should expose modules from the container", async () => { + const container = __non_webpack_require__("./container-file.js"); + expect(container).toBeTypeOf("object"); + expect(container.override).toBeTypeOf("function"); + container.override({ + value: () => + new Promise(resolve => { + setTimeout(() => { + resolve(() => ({ + __esModule: true, + default: "overriden-value" + })); + }, 100); + }) + }); + const testFactory = await container.get("test"); + expect(testFactory).toBeTypeOf("function"); + expect(testFactory()).toEqual( + nsObj({ + default: "test overriden-value" + }) + ); +}); diff --git a/test/configCases/container/container-entry-overridables/test.js b/test/configCases/container/container-entry-overridables/test.js new file mode 100644 index 000000000..20449c1d0 --- /dev/null +++ b/test/configCases/container/container-entry-overridables/test.js @@ -0,0 +1,3 @@ +import value from "./value"; + +export default `test ${value}`; diff --git a/test/configCases/container/container-entry-overridables/value.js b/test/configCases/container/container-entry-overridables/value.js new file mode 100644 index 000000000..a0698aa0d --- /dev/null +++ b/test/configCases/container/container-entry-overridables/value.js @@ -0,0 +1 @@ +export default "value"; diff --git a/test/configCases/container/container-entry-overridables/webpack.config.js b/test/configCases/container/container-entry-overridables/webpack.config.js new file mode 100644 index 000000000..3d53ac036 --- /dev/null +++ b/test/configCases/container/container-entry-overridables/webpack.config.js @@ -0,0 +1,19 @@ +const ContainerPlugin = require("../../../../lib/container/ContainerPlugin"); + +module.exports = { + plugins: [ + new ContainerPlugin({ + name: "container", + filename: "container-file.js", + library: { + type: "commonjs-module" + }, + exposes: { + test: "./test" + }, + overridables: { + value: "./value" + } + }) + ] +};