Closed ScriptedAlchemy closed 2 years ago
Mind updating the README with the new output format?
@jacob-ebey done!
Oh interesting. It's just the given "name" mapped to a chunk ID? How is this going to be utilized?
In next.js for federated SSR, I can grab any federated imports in the project without a problem and sideload them into the loadable manifest.
However when I have nested federated imports, in production mode, the only thing i can gain access to is a proxy object where loadable looks for the import key (checkout/title) and the module id it needs is the module id in the remote container. I need to be able to correlate name to module id in order to push it into next.js at runtime so when the client hydrates its got a full list of all async import ids otherwise ill get flicker and hydration issues as even tho the chunk is SSR'd on the page, the promise wasn't pre-resolved before render starts.
This is an interesting scenario because usually id be looking for IDs elsewhere, but in this case i need to search for the module ID in the remote, not the ID of the import in the host. Like a reverse-reverse lookup
Do you have another plugin or something that adds the external module ID to the stats? As far as I'm aware this external ID isn't grabbed by webpack at compile time, so isn't this ID the internal representation of the 3rd party module just for this compilations resolution graph?
Its a long story. Im using your plugin instead of forking it - I take what it emits and embed it into webpack federation API, then recreate a mini module graph as each remote attaches itself to a host. So while they are all only have their own information. When combined at runtime I can determine the external module id since I now know what remote imports the current remote has inside it.
Id already made these edits internally in node modules and it does what I needed it to :P
Excuse the mess. My loops are pretty rough but you can see the remoteModule line toward the bottom where I do the "reverse reverse" lookup inside the host.
const extractChunkCorrelation = (remoteContainer, lookup, request) => {
if (
remoteContainer &&
remoteContainer.chunkMap &&
remoteContainer.chunkMap.federatedModules
) {
const path = remoteContainer.path.split("@")[1];
const [baseurl] = path.split("static/ssr");
remoteContainer.chunkMap.federatedModules.map((federatedRemote) => {
federatedRemote.exposes[request].forEach((remoteChunks) => {
remoteChunks.chunks.map((chunk) => {
if (!lookup.files.includes(new URL(chunk, baseurl).href)) {
lookup.files.push(new URL(chunk, baseurl).href);
}
});
});
});
} else {
console.warn(
"Module Federation:",
"no federated modules in chunk map OR experiments.flushChunks is disabled"
);
}
};
const requireMethod =
typeof __non_webpack_require__ !== "undefined"
? __non_webpack_require__
: require;
const requestPath = path.join(
process.cwd(),
".next",
"server/pages",
"../../react-loadable-manifest.json"
);
let remotes = {};
const loadableManifest = requireMethod(requestPath);
requireMethod.cache[requestPath].exports = new Proxy(loadableManifest, {
get(target, prop, receiver) {
if (!target[prop]) {
let remoteImport = prop.split("->")[1]
if (remoteImport) {
remoteImport = remoteImport.trim();
const [remote, module] = remoteImport.split("/");
if (!remotes[remote]) {
Object.assign(remotes,generateDynamicRemoteScript(global.loadedRemotes[remote]))
}
const dynamicLoadableManifestItem = {
id: prop,
files: [],
};
// TODO: figure out who is requesting module
let remoteModuleContainerId
Object.values(global.loadedRemotes).find((remote)=> {
if(remote.chunkMap && remote.chunkMap.federatedModules[0] && remote.chunkMap.federatedModules[0].remoteModules) {
if(remote.chunkMap.federatedModules[0].remoteModules[remoteImport]) {
remoteModuleContainerId = remote.chunkMap.federatedModules[0].remoteModules[remoteImport]
return true
}
}
})
if(remoteModuleContainerId) {
dynamicLoadableManifestItem.id = remoteModuleContainerId
}
extractChunkCorrelation(
global.loadedRemotes[remote],
dynamicLoadableManifestItem,
`./${module}`
);
return dynamicLoadableManifestItem;
}
}
return target[prop];
},
});
Gotcha.
Much love <3 ill watch npm for a version bump
Adding Remote modules to stats plugin. Needed to find and correlate nested remotes during SSR