Skip to content

Commit 41b3cea

Browse files
Nstttclaude
andcommitted
fix(esbuild): fix esbuild 0.25.0 compatibility and remote module loading
- Use esbuild context() API for watch mode (0.25.0 removed watch option) - Fix remote loading to use container.loadRemote() instead of import maps - Enables proper dynamic loading of federated modules at runtime 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 47f1818 commit 41b3cea

File tree

2 files changed

+20
-13
lines changed

2 files changed

+20
-13
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/linkRemotesPlugin.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
import path from 'path';
22
import { NormalizedFederationConfig } from '../../lib/config/federation-config';
33

4-
// relys on import map since i dont know the named exports of a remote to return.
4+
// Creates a virtual module that uses loadRemote to dynamically load the remote module
5+
// Since we don't know the named exports at build time, we load the module and re-export everything
56
export const createVirtualRemoteModule = (name: string, ref: string) => `
6-
export * from ${JSON.stringify('federationRemote/' + ref)}
7+
const container = __FEDERATION__.__INSTANCES__.find(container => container.name === ${JSON.stringify(name)}) || __FEDERATION__.__INSTANCES__[0];
8+
const mfRemoteModule = await container.loadRemote(${JSON.stringify(ref)});
9+
const { default: defaultExport, ...namedExports } = mfRemoteModule || {};
10+
export default defaultExport !== undefined ? defaultExport : mfRemoteModule;
11+
export { namedExports };
12+
// Re-export common patterns - App is commonly used in React federated modules
13+
export const App = mfRemoteModule?.App;
14+
export const Component = mfRemoteModule?.Component;
715
`;
816

917
export const linkRemotesPlugin = (config: NormalizedFederationConfig) => ({
@@ -24,14 +32,6 @@ export const linkRemotesPlugin = (config: NormalizedFederationConfig) => ({
2432
return { path: args.path, namespace: 'remote-module' };
2533
});
2634

27-
build.onResolve({ filter: /^federationRemote/ }, async (args: any) => {
28-
return {
29-
path: args.path.replace('federationRemote/', ''),
30-
external: true,
31-
namespace: 'externals',
32-
};
33-
});
34-
3535
build.onLoad({ filter, namespace: 'remote-module' }, async (args: any) => {
3636
return {
3737
contents: createVirtualRemoteModule(config.name, args.path),

0 commit comments

Comments
 (0)