Skip to content

Commit 897dc5a

Browse files
authored
fix: enqueue resolvers before ScriptManager init (#1156)
* fix: use resolver queue instead of async * fix: tests * test: add cases for uninitialized ScriptManager * chore: changeset * fix: naming * refactor: cleanup * chore: update changeset
1 parent 111d96f commit 897dc5a

File tree

9 files changed

+261
-190
lines changed

9 files changed

+261
-190
lines changed

.changeset/cold-kids-yawn.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@callstack/repack": patch
3+
---
4+
5+
Fix registering resolvers for remotes in ResolverPlugin when ScriptManager is not yet initialized

packages/repack/src/modules/FederationRuntimePlugins/ResolverPlugin.ts

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ import type {
22
FederationHost,
33
FederationRuntimePlugin,
44
} from '@module-federation/enhanced/runtime';
5-
import type * as RepackClient from '../ScriptManager/index.js';
5+
import type { ScriptLocator } from '../ScriptManager/index.js';
66

77
type MFRemote = Parameters<FederationHost['registerRemotes']>[0][0];
88

99
export type RepackResolverPluginConfiguration =
10-
| Omit<RepackClient.ScriptLocator, 'url'>
11-
| ((url: string) => Promise<RepackClient.ScriptLocator>);
10+
| Omit<ScriptLocator, 'url'>
11+
| ((url: string) => Promise<ScriptLocator>);
1212

1313
const createScriptLocator = async (
1414
entryUrl: string,
@@ -44,13 +44,6 @@ const registerResolver = async (
4444
remoteInfo: MFRemote,
4545
config?: RepackResolverPluginConfiguration
4646
) => {
47-
// when ScriptManager.shared.resolveScript is called, registerResolver
48-
// should evaluate before it and and the resolver will be registered
49-
// before any remote script is resolved
50-
const { ScriptManager } = (await import(
51-
'../ScriptManager/index.js'
52-
)) as typeof RepackClient;
53-
5447
// when manifest is used, the valid entry URL comes from the version field
5548
// otherwise, the entry URL comes from the entry field which has the correct publicPath for the remote set
5649
let entryUrl: string | undefined;
@@ -67,29 +60,36 @@ const registerResolver = async (
6760
);
6861
}
6962

70-
ScriptManager.shared.addResolver(
71-
async (scriptId, caller, referenceUrl) => {
72-
if (scriptId === remoteInfo.name || caller === remoteInfo.name) {
73-
// referenceUrl should always be present and this should never happen
74-
if (!referenceUrl) {
75-
throw new Error('[RepackResolverPlugin] Reference URL is missing');
76-
}
77-
78-
const url = rebaseRemoteUrl(referenceUrl, entryUrl);
79-
const locator = await createScriptLocator(url, config);
80-
return locator;
63+
const resolver = async (
64+
scriptId: string,
65+
caller?: string,
66+
referenceUrl?: string
67+
) => {
68+
if (scriptId === remoteInfo.name || caller === remoteInfo.name) {
69+
// referenceUrl should always be present and this should never happen
70+
if (!referenceUrl) {
71+
throw new Error('[RepackResolverPlugin] Reference URL is missing');
8172
}
82-
},
83-
{ key: remoteInfo.name }
84-
);
73+
74+
const url = rebaseRemoteUrl(referenceUrl, entryUrl);
75+
const locator = await createScriptLocator(url, config);
76+
return locator;
77+
}
78+
};
79+
80+
const runtime = __webpack_require__.repack.shared;
81+
if (runtime.scriptManager) {
82+
runtime.scriptManager.addResolver(resolver, { key: remoteInfo.name });
83+
} else {
84+
runtime.enqueuedResolvers.push([resolver, { key: remoteInfo.name }]);
85+
}
8586
};
8687

8788
const RepackResolverPlugin: (
8889
config?: RepackResolverPluginConfiguration
8990
) => FederationRuntimePlugin = (config) => ({
9091
name: 'repack-resolver-plugin',
9192
registerRemote: (args) => {
92-
// asynchronously add a resolver for the remote
9393
registerResolver(args.remote, config);
9494
return args;
9595
},

packages/repack/src/modules/FederationRuntimePlugins/__tests__/CorePlugin.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ webpackRequireMock.l = () => {};
2929
webpackRequireMock.u = (id: string) => `${id}.chunk.bundle`;
3030
webpackRequireMock.p = () => '';
3131
webpackRequireMock.repack = {
32-
shared: { scriptManager: undefined },
32+
shared: { scriptManager: undefined, enqueuedResolvers: [] },
3333
};
3434

3535
globalThis.__webpack_require__ = webpackRequireMock;

0 commit comments

Comments
 (0)