Forked from maraisr/webpack-access-federated-containers-plugin.js
Created
March 31, 2022 01:28
-
-
Save PatrickJS/9befc4a3685363a2cb43c9ef7fcad959 to your computer and use it in GitHub Desktop.
webpack-access-federated-containers-plugin.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Makes your remote containers low level API accessible via: | |
import accessFederatedContainer from "access-federated-containers"; | |
accessFederatedContainer("app2") | |
*/ | |
/** @typedef {import("webpack").Compiler} Compiler */ | |
/** @typedef {import("webpack").Compilation} Compilation */ | |
const VirtualModulesPlugin = require("webpack-virtual-modules"); | |
const PLUGIN_NAME = "AccessFederatedContainersPlugin"; | |
/** | |
* | |
* @param {import("webpack").Module[]} modules | |
*/ | |
function createAccessFederatedContainersModule(modules) { | |
const containerAccessors = modules.map((mod) => { | |
const name = mod.userRequest.replace("webpack/container/reference/", ""); | |
const chunks = mod | |
.getChunks() | |
.filter((chunk) => !!chunk.id) | |
.map((chunk) => `__webpack_require__.e(${JSON.stringify(chunk.id)})`); | |
return `${JSON.stringify(name)}: () => Promise.all([${chunks.join( | |
", " | |
)}]).then(() => __webpack_require__(${JSON.stringify(mod.id)}))`; | |
}); | |
return ` | |
const containerAccessors = { | |
${containerAccessors.join(",\n ")} | |
}; | |
async function accessFederatedContainer(containerName) { | |
const accessor = containerAccessors[containerName]; | |
if (!accessor) { | |
throw new Error(\`Can not access container "\${containerName}".\`); | |
} | |
return await accessor(); | |
} | |
export default accessFederatedContainer;`; | |
} | |
const defaultOptions = { | |
exposedAs: "access-federated-containers", | |
}; | |
class AccessFederatedContainersPlugin { | |
constructor(options = defaultOptions) { | |
this._rawRequest = options.exposedAs || defaultOptions.exposedAs; | |
this._exposedAs = `node_modules/${this._rawRequest}`; | |
} | |
/** | |
* @param {Compiler} compiler | |
*/ | |
apply(compiler) { | |
const virtualModules = new VirtualModulesPlugin({ | |
[this._exposedAs]: "", | |
}); | |
virtualModules.apply(compiler); | |
let updatedAccessContainerModule = false; | |
const addedModules = new Map(); | |
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => { | |
compilation.hooks.needAdditionalPass.tap(PLUGIN_NAME, () => { | |
console.log( | |
"updatedAccessContainerModule", | |
updatedAccessContainerModule ? "true" : "false" | |
); | |
let result = updatedAccessContainerModule; | |
updatedAccessContainerModule = false; | |
return result; | |
}); | |
compilation.hooks.afterOptimizeModuleIds.tap(PLUGIN_NAME, (modules) => { | |
const filteredModules = [...modules].filter( | |
(mod) => | |
(mod.constructor.name === "ExternalModule" && | |
mod.userRequest && | |
mod.userRequest.startsWith("webpack/container/reference/")) | |
); | |
if ( | |
filteredModules.length > 0 && | |
filteredModules.some((mod) => !addedModules.has(mod.id)) | |
) { | |
updatedAccessContainerModule = true; | |
filteredModules.forEach((mod) => addedModules.set(mod.id, mod)); | |
virtualModules.writeModule( | |
this._exposedAs, | |
createAccessFederatedContainersModule([...addedModules.values()]) | |
); | |
} | |
}); | |
}); | |
} | |
} | |
module.exports = AccessFederatedContainersPlugin; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment