add overridables to ContainerPlugin

This commit is contained in:
Tobias Koppers 2020-02-26 22:32:48 +01:00
parent 95347e17d5
commit 25cd520012
8 changed files with 69 additions and 20 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,3 @@
import value from "./value";
export default `test ${value}`;

View File

@ -0,0 +1 @@
export default "value";

View File

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