Skip to content

Instantly share code, notes, and snippets.

@jacob-ebey
Created December 9, 2020 08:27
Show Gist options
  • Save jacob-ebey/23aee3036c0c0c78a0b9369a5d8286ff to your computer and use it in GitHub Desktop.
Save jacob-ebey/23aee3036c0c0c78a0b9369a5d8286ff to your computer and use it in GitHub Desktop.
FederatedStartupCodePlugin.js
const fs = require("fs");
const path = require("path");
const Template = require("webpack/lib/Template");
const SingleEntryPlugin = require("webpack/lib/SingleEntryPlugin");
const VirtualModulesPlugin = require("webpack-virtual-modules");
const PLUGIN_NAME = "FederatedStartupCodePlugin";
/**
* @typedef {object} FederatedStartupCodeOptions
* @property {string} name
* @property {code | undefined} code
*/
class FederatedStartupCodePlugin {
/**
*
* @param {FederatedStartupCodeOptions} options
*/
constructor(options) {
if (!options) {
throw new Error("No options provided.");
}
if (!options.name) {
throw new Error("No name provided.");
}
this._name = options.name;
this._modulePath = `./${options.name}-startup.js`;
this._code = options.code;
}
writeCode(code) {
this._code = code;
}
/**
* @param {import("webpack").Compiler} compiler
*/
apply(compiler) {
const virtualModules = new VirtualModulesPlugin({
[this._modulePath]: "",
});
compiler.options.entry =
typeof compiler.options.entry === "object"
? Object.assign({}, compiler.options.entry, {
[this._name]: { import: [this._modulePath] },
})
: {
main: compiler.options.entry,
[this._name]: { import: [this._modulePath] },
};
compiler.hooks.compile.tap(PLUGIN_NAME, () => {
const code = Template.asString([
"const exports = (() => {",
Template.indent([
"return Object.keys(__webpack_modules__).reduce((containerModule, moduleId) => {",
Template.indent([
"if (moduleId !== module.id) {",
Template.indent([
"const currentModule = __webpack_require__(moduleId);",
`if (typeof currentModule.get === "function" && typeof currentModule.init === "function") {`,
Template.indent(["return currentModule;"]),
"}",
]),
"}",
"return containerModule;",
]),
"}, {});",
]),
"})();",
"((exports) => {",
Template.indent(this._code || ""),
"})(exports);",
"module.exports = exports;",
]);
virtualModules.writeModule(this._modulePath, code);
});
virtualModules.apply(compiler);
}
}
module.exports = FederatedStartupCodePlugin;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment