Skip to content

Commit 282ca34

Browse files
committed
fix(esbuild): fix esbuild 0.25.0 compatibility and remote module loading module-federation#4255
1 parent 47f1818 commit 282ca34

File tree

2 files changed

+67
-23
lines changed

2 files changed

+67
-23
lines changed

apps/esbuild/build/build-common.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ async function buildProject(projectName, watch) {
1111

1212
fs.rmSync(outputPath, { force: true, recursive: true });
1313

14-
await esbuild.build({
14+
const buildOptions = {
1515
entryPoints: [path.join(projectName, 'main.ts')],
1616
outdir: outputPath,
1717
bundle: true,
@@ -28,8 +28,15 @@ async function buildProject(projectName, watch) {
2828
require(path.join('../', projectName, 'federation.config.js')),
2929
),
3030
],
31-
watch,
32-
});
31+
};
32+
33+
if (watch) {
34+
const ctx = await esbuild.context(buildOptions);
35+
await ctx.watch();
36+
console.log(`Watching ${projectName} for changes...`);
37+
} else {
38+
await esbuild.build(buildOptions);
39+
}
3340

3441
['index.html', 'favicon.ico', 'styles.css'].forEach((file) => {
3542
fs.copyFileSync(path.join(projectName, file), path.join(outputPath, file));

packages/esbuild/src/adapters/lib/containerReference.ts

Lines changed: 57 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -59,28 +59,38 @@ export const buildFederationHost = (config: NormalizedFederationConfig) => {
5959
const runtimePlugin = () => ({
6060
name: 'import-maps-plugin',
6161
async init(args) {
62-
const remotePrefetch = args.options.remotes.map(async (remote) => {
63-
console.log('remote', remote);
64-
if (remote.type === 'esm') {
65-
await import(remote.entry);
66-
}
67-
});
68-
69-
await Promise.all(remotePrefetch);
70-
if (typeof moduleMap !== 'undefined') {
71-
const map = Object.keys(moduleMap).reduce((acc, expose) => {
72-
const importMap = importShim.getImportMap().imports;
73-
const key = args.origin.name + expose.replace('.', '');
74-
if (!importMap[key]) {
75-
const encodedModule = encodeInlineESM(
76-
createVirtualRemoteModule(args.origin.name, key, moduleMap[expose].exports)
77-
);
78-
acc[key] = encodedModule;
62+
// Load all remotes and collect their moduleMaps
63+
const remotesWithModuleMaps = await Promise.all(
64+
args.options.remotes.map(async (remote) => {
65+
console.log('remote', remote);
66+
if (remote.type === 'esm') {
67+
const remoteModule = await import(remote.entry);
68+
return { remote, moduleMap: remoteModule.moduleMap };
69+
}
70+
return { remote, moduleMap: null };
71+
})
72+
);
73+
74+
// Build import map entries for all remote modules
75+
const allImports = {};
76+
for (const { remote, moduleMap } of remotesWithModuleMaps) {
77+
if (moduleMap && typeof moduleMap === 'object') {
78+
for (const expose of Object.keys(moduleMap)) {
79+
const currentImportMap = importShim.getImportMap().imports;
80+
// Use remote name + expose path (e.g., "mfe1/component")
81+
const key = remote.name + expose.replace('.', '');
82+
if (!currentImportMap[key] && !allImports[key]) {
83+
const encodedModule = encodeInlineESM(
84+
createVirtualRemoteModule(remote.name, key, moduleMap[expose].exports)
85+
);
86+
allImports[key] = encodedModule;
87+
}
7988
}
80-
return acc;
81-
}, {});
89+
}
90+
}
8291
83-
await importShim.addImportMap({ imports: map });
92+
if (Object.keys(allImports).length > 0) {
93+
await importShim.addImportMap({ imports: allImports });
8494
}
8595
8696
return args;
@@ -96,6 +106,33 @@ export const buildFederationHost = (config: NormalizedFederationConfig) => {
96106
97107
await Promise.all(mfHoZJ92.initializeSharing('default', 'version-first'));
98108
109+
// Ensure import maps are registered before any code that uses remotes runs
110+
const remotesList = ${remoteConfigs};
111+
const allImports = {};
112+
for (const remote of remotesList) {
113+
if (remote.type === 'esm') {
114+
try {
115+
const remoteModule = await import(remote.entry);
116+
const moduleMap = remoteModule.moduleMap;
117+
if (moduleMap && typeof moduleMap === 'object') {
118+
for (const expose of Object.keys(moduleMap)) {
119+
const key = remote.name + expose.replace('.', '');
120+
if (!allImports[key]) {
121+
const encodedModule = encodeInlineESM(
122+
createVirtualRemoteModule(remote.name, key, moduleMap[expose].exports)
123+
);
124+
allImports[key] = encodedModule;
125+
}
126+
}
127+
}
128+
} catch (e) {
129+
console.error('Failed to load remote:', remote.name, e);
130+
}
131+
}
132+
}
133+
if (Object.keys(allImports).length > 0) {
134+
await importShim.addImportMap({ imports: allImports });
135+
}
99136
100137
`;
101138
};

0 commit comments

Comments
 (0)