mirror of https://github.com/webpack/webpack.git
Merge pull request #10646 from ScriptedAlchemy/patch-1
fix: module federation plugin library should be optional
This commit is contained in:
commit
46db02ca2c
|
@ -43,7 +43,7 @@ module.exports = class ContainerReferencePlugin {
|
||||||
remoteExternals[`container-reference/${key}`] = value;
|
remoteExternals[`container-reference/${key}`] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
new ExternalsPlugin(remoteType, remoteExternals).apply(compiler);
|
new ExternalsPlugin(remoteType || "var", remoteExternals).apply(compiler);
|
||||||
|
|
||||||
compiler.hooks.compilation.tap(
|
compiler.hooks.compilation.tap(
|
||||||
"ContainerReferencePlugin",
|
"ContainerReferencePlugin",
|
||||||
|
|
|
@ -22,18 +22,31 @@ class ModuleFederationPlugin {
|
||||||
*/
|
*/
|
||||||
apply(compiler) {
|
apply(compiler) {
|
||||||
const { options } = this;
|
const { options } = this;
|
||||||
|
if (
|
||||||
|
options.library &&
|
||||||
|
!compiler.options.output.enabledLibraryTypes.includes(
|
||||||
|
options.library.type
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
compiler.options.output.enabledLibraryTypes.push(options.library.type);
|
||||||
|
}
|
||||||
|
compiler.hooks.afterPlugins.tap("ModuleFederationPlugin", () => {
|
||||||
new ContainerPlugin({
|
new ContainerPlugin({
|
||||||
name: options.name,
|
name: options.name,
|
||||||
library: options.library,
|
library: options.library || compiler.options.output.library,
|
||||||
filename: options.filename,
|
filename: options.filename,
|
||||||
exposes: options.exposes,
|
exposes: options.exposes,
|
||||||
overridables: options.shared
|
overridables: options.shared
|
||||||
}).apply(compiler);
|
}).apply(compiler);
|
||||||
new ContainerReferencePlugin({
|
new ContainerReferencePlugin({
|
||||||
remoteType: options.remoteType || options.library.type,
|
remoteType:
|
||||||
|
options.remoteType ||
|
||||||
|
(options.library && options.library.type) ||
|
||||||
|
compiler.options.externalsType,
|
||||||
remotes: options.remotes,
|
remotes: options.remotes,
|
||||||
overrides: options.shared
|
overrides: options.shared
|
||||||
}).apply(compiler);
|
}).apply(compiler);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
module.exports = "dep";
|
|
@ -0,0 +1,3 @@
|
||||||
|
it("should import the correct modules", () => {
|
||||||
|
return import("./module").then(({ test }) => test());
|
||||||
|
});
|
|
@ -0,0 +1,19 @@
|
||||||
|
import abc from "abc/system-hello-world";
|
||||||
|
import def, { module } from "def/system-hello-world";
|
||||||
|
import def2, { module as module2 } from "def/system-hello/other/world";
|
||||||
|
import other from "other/other";
|
||||||
|
import otherSelf from "other/self";
|
||||||
|
import self from "self/self";
|
||||||
|
import selfOther from "self/other";
|
||||||
|
|
||||||
|
export function test() {
|
||||||
|
expect(abc).toBe("abc system-hello-world");
|
||||||
|
expect(def).toBe("def");
|
||||||
|
expect(def2).toBe("def");
|
||||||
|
expect(module).toBe("system-hello-world");
|
||||||
|
expect(module2).toBe("system-hello/other/world");
|
||||||
|
expect(other).toBe("other and dep");
|
||||||
|
expect(otherSelf).toBe("self and dep");
|
||||||
|
expect(self).toBe("self and dep");
|
||||||
|
expect(selfOther).toBe("other and dep");
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
import andBack from "other/dep";
|
||||||
|
|
||||||
|
export default `other and ${andBack}`;
|
|
@ -0,0 +1,3 @@
|
||||||
|
import andBack from "self/dep";
|
||||||
|
|
||||||
|
export default `self and ${andBack}`;
|
|
@ -0,0 +1,36 @@
|
||||||
|
const System = require("../../../helpers/fakeSystem");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
beforeExecute: () => {
|
||||||
|
System.init();
|
||||||
|
},
|
||||||
|
moduleScope(scope) {
|
||||||
|
System.setRequire(scope.require);
|
||||||
|
scope.System = System;
|
||||||
|
System.set("ABC", {
|
||||||
|
get(module) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
setTimeout(() => {
|
||||||
|
resolve(() => "abc " + module);
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
System.set("DEF", {
|
||||||
|
get(module) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
setTimeout(() => {
|
||||||
|
resolve(() => ({
|
||||||
|
__esModule: true,
|
||||||
|
module,
|
||||||
|
default: "def"
|
||||||
|
}));
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
afterExecute: () => {
|
||||||
|
System.execute("(anonym)");
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,35 @@
|
||||||
|
const ModuleFederationPlugin = require("../../../../lib/container/ModuleFederationPlugin");
|
||||||
|
|
||||||
|
function createConfig() {
|
||||||
|
return {
|
||||||
|
output: {
|
||||||
|
libraryTarget: "system"
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new ModuleFederationPlugin({
|
||||||
|
name: "container",
|
||||||
|
filename: "container.js",
|
||||||
|
exposes: ["./other", "./self", "./dep"],
|
||||||
|
remotes: {
|
||||||
|
abc: "ABC",
|
||||||
|
def: "DEF",
|
||||||
|
self: "./container.js",
|
||||||
|
other: "./container2.js"
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
new ModuleFederationPlugin({
|
||||||
|
name: "container2",
|
||||||
|
filename: "container2.js",
|
||||||
|
exposes: ["./other", "./self", "./dep"],
|
||||||
|
remotes: {
|
||||||
|
abc: "ABC",
|
||||||
|
def: "DEF",
|
||||||
|
self: "./container2.js",
|
||||||
|
other: "./container.js"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = createConfig();
|
|
@ -6,7 +6,7 @@ const System = {
|
||||||
if (typeof name !== "string") {
|
if (typeof name !== "string") {
|
||||||
fn = deps;
|
fn = deps;
|
||||||
deps = name;
|
deps = name;
|
||||||
name = "(anonym)";
|
name = System._nextName;
|
||||||
}
|
}
|
||||||
if (!Array.isArray(deps)) {
|
if (!Array.isArray(deps)) {
|
||||||
fn = deps;
|
fn = deps;
|
||||||
|
@ -17,6 +17,16 @@ const System = {
|
||||||
throw new Error(`Module ${name} calls dynamicExport too late`);
|
throw new Error(`Module ${name} calls dynamicExport too late`);
|
||||||
}
|
}
|
||||||
entry.exports = result;
|
entry.exports = result;
|
||||||
|
for (const mod of Object.keys(System.registry)) {
|
||||||
|
const m = System.registry[mod];
|
||||||
|
if (!m.deps) continue;
|
||||||
|
for (let i = 0; i < m.deps.length; i++) {
|
||||||
|
const dep = m.deps[i];
|
||||||
|
if (dep !== name) continue;
|
||||||
|
const setters = m.mod.setters[i];
|
||||||
|
setters(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
const systemContext = {
|
const systemContext = {
|
||||||
meta: {
|
meta: {
|
||||||
|
@ -52,7 +62,19 @@ const System = {
|
||||||
};
|
};
|
||||||
System.registry[name] = entry;
|
System.registry[name] = entry;
|
||||||
},
|
},
|
||||||
|
set: (name, exports) => {
|
||||||
|
System.registry[name] = {
|
||||||
|
name,
|
||||||
|
executed: true,
|
||||||
|
exports
|
||||||
|
};
|
||||||
|
},
|
||||||
registry: undefined,
|
registry: undefined,
|
||||||
|
_require: undefined,
|
||||||
|
_nextName: "(anonym)",
|
||||||
|
setRequire: req => {
|
||||||
|
System._require = req;
|
||||||
|
},
|
||||||
init: modules => {
|
init: modules => {
|
||||||
System.registry = {};
|
System.registry = {};
|
||||||
if (modules) {
|
if (modules) {
|
||||||
|
@ -71,15 +93,25 @@ const System = {
|
||||||
return System.ensureExecuted(name);
|
return System.ensureExecuted(name);
|
||||||
},
|
},
|
||||||
ensureExecuted: name => {
|
ensureExecuted: name => {
|
||||||
const m = System.registry[name];
|
let m = System.registry[name];
|
||||||
if (!m) throw new Error(`Module ${name} not registered`);
|
if (!m && System._require) {
|
||||||
|
const oldName = System._nextName;
|
||||||
|
System._nextName = name;
|
||||||
|
System._require(name);
|
||||||
|
System._nextName = oldName;
|
||||||
|
m = System.registry[name];
|
||||||
|
}
|
||||||
|
if (!m) {
|
||||||
|
throw new Error(`Module ${name} not registered`);
|
||||||
|
}
|
||||||
if (!m.executed) {
|
if (!m.executed) {
|
||||||
m.executed = true;
|
m.executed = true;
|
||||||
for (let i = 0; i < m.deps.length; i++) {
|
for (let i = 0; i < m.deps.length; i++) {
|
||||||
const dep = m.deps[i];
|
const dep = m.deps[i];
|
||||||
const setters = m.mod.setters[i];
|
const setters = m.mod.setters[i];
|
||||||
System.ensureExecuted(dep);
|
System.ensureExecuted(dep);
|
||||||
setters(System.registry[dep].exports);
|
const { exports } = System.registry[dep];
|
||||||
|
if (exports !== undefined) setters(exports);
|
||||||
}
|
}
|
||||||
m.mod.execute();
|
m.mod.execute();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue