Skip to content

Commit 6c7174e

Browse files
refactor(enhanced): resolve alias-aware consumes in afterResolve with caching (#4061)
1 parent c7a0d1d commit 6c7174e

File tree

62 files changed

+1674
-606
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1674
-606
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
'@module-federation/enhanced': patch
3+
---
4+
5+
fix(enhanced): ConsumeSharedPlugin alias-aware and virtual resource handling
6+
7+
- Skip `data:` (virtual) resources in `afterResolve` and `createModule` so webpack's scheme resolver handles them (fixes container virtual-entry compile failure)
8+
- Broaden alias-aware matching in `afterResolve` to include deep-path shares that start with the resolved package name (e.g. `next/dist/compiled/react`), ensuring aliased modules are consumed from federation when configured
9+
- Avoid converting explicit relative/absolute requests into consumes to preserve local nested resolution (fixes deep module sharing version selection)
10+
- Keep prefix and node_modules suffix matching intact; no behavior change there
11+
12+
These changes restore expected behavior for:
13+
- Virtual entry compilation
14+
- Deep module sharing (distinct versions for nested paths)
15+
- Alias-based sharing (Next.js compiled React)
16+

.github/workflows/e2e-manifest.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ jobs:
4646

4747
- name: E2E Test for Manifest Demo Development
4848
if: steps.check-ci.outcome == 'success'
49-
run: pnpm run app:manifest:dev & echo "done" && npx wait-on tcp:3009 && npx wait-on tcp:3012 && npx wait-on http://127.0.0.1:4001/ && npx nx run-many --target=e2e --projects=manifest-webpack-host --parallel=2 && npx kill-port 3013 3009 3010 3011 3012 4001
49+
run: node tools/scripts/run-manifest-e2e.mjs --mode=dev
5050

5151
- name: E2E Test for Manifest Demo Production
5252
if: steps.check-ci.outcome == 'success'
53-
run: pnpm run app:manifest:prod & echo "done" && npx wait-on tcp:3009 && npx wait-on tcp:3012 && npx wait-on http://127.0.0.1:4001/ && npx nx run-many --target=e2e --projects=manifest-webpack-host --parallel=1 && npx kill-port 3013 3009 3010 3011 3012 4001
53+
run: node tools/scripts/run-manifest-e2e.mjs --mode=prod

.gitignore

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ ssg
9090
__mocks__/
9191

9292
# test mock modules
93-
!packages/enhanced/test/configCases/**/**/node_modules
94-
!packages/enhanced/test/configCases/sharing/share-with-aliases/node_modules/next/dist
95-
!packages/enhanced/test/configCases/sharing/share-with-aliases-provide-only/node_modules/next/dist
93+
# Keep ALL test configCases node_modules (and all nested files) tracked,
94+
# so we don't need per-path exceptions like next/dist.
95+
!packages/enhanced/test/configCases/**/node_modules/
96+
!packages/enhanced/test/configCases/**/node_modules/**

nx.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"$schema": "./node_modules/nx/schemas/nx-schema.json",
3+
"useDaemonProcess": false,
34
"targetDefaults": {
45
"build": {
56
"inputs": ["production", "^production"],

packages/enhanced/src/declarations/plugins/sharing/ConsumeSharedPlugin.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ export interface ConsumeSharedPluginOptions {
2525
* Share scope name used for all consumed modules (defaults to 'default').
2626
*/
2727
shareScope?: string | string[];
28+
/**
29+
* Experimental features configuration.
30+
*/
31+
experiments?: {
32+
/** Enable alias-aware consuming via NormalModuleFactory.afterResolve (experimental). */
33+
aliasConsumption?: boolean;
34+
};
2835
}
2936
/**
3037
* Modules that should be consumed from share scope. Property names are used to match requested modules in this compilation. Relative requests are resolved, module requests are matched unresolved, absolute paths will match resolved requests. A trailing slash will match all requests with this prefix. In this case shareKey must also have a trailing slash.

packages/enhanced/src/declarations/plugins/sharing/SharePlugin.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ export interface SharePluginOptions {
2525
* Modules that should be shared in the share scope. When provided, property names are used to match requested modules in this compilation.
2626
*/
2727
shared: Shared;
28+
/**
29+
* Experimental features configuration.
30+
*/
31+
experiments?: {
32+
/** Enable alias-aware consuming via NormalModuleFactory.afterResolve (experimental). */
33+
aliasConsumption?: boolean;
34+
};
2835
}
2936
/**
3037
* Modules that should be shared in the share scope. Property names are used to match requested modules in this compilation. Relative requests are resolved, module requests are matched unresolved, absolute paths will match resolved requests. A trailing slash will match all requests with this prefix. In this case shareKey must also have a trailing slash.

packages/enhanced/src/lib/container/ModuleFederationPlugin.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ class ModuleFederationPlugin implements WebpackPluginInstance {
107107
(new RemoteEntryPlugin(options) as unknown as WebpackPluginInstance).apply(
108108
compiler,
109109
);
110+
111+
// Do not use process.env for alias consumption; flag is forwarded via options
110112
if (options.experiments?.provideExternalRuntime) {
111113
if (options.exposes) {
112114
throw new Error(
@@ -212,10 +214,15 @@ class ModuleFederationPlugin implements WebpackPluginInstance {
212214
}).apply(compiler);
213215
}
214216
if (options.shared) {
215-
new SharePlugin({
217+
// Build SharePlugin options and pass through aliasConsumption directly
218+
const shareOpts = {
216219
shared: options.shared,
217220
shareScope: options.shareScope,
218-
}).apply(compiler);
221+
experiments: {
222+
aliasConsumption: options.experiments?.aliasConsumption,
223+
},
224+
};
225+
new SharePlugin(shareOpts).apply(compiler);
219226
}
220227
});
221228

0 commit comments

Comments
 (0)