Skip to content

Commit 5ac18a4

Browse files
feat: implement nodeModulesReconstructedLookup feature for PR7
- Add nodeModulesReconstructedLookup support to ProvideSharedPlugin with Stage 2 reconstruction logic - Implement comprehensive node_modules path reconstruction in ConsumeSharedPlugin factorize hook - Add nodeModulesReconstructedLookup property to SharePlugin configurations - Fix prefix request filtering logic using _originalPrefix approach for proper remainder matching - Create comprehensive test case structure for nodeModulesReconstructedLookup feature - Update type definitions to include nodeModulesReconstructedLookup in all sharing interfaces - Align implementation with share-filter branch specifications 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 3296fd4 commit 5ac18a4

File tree

18 files changed

+405714
-6
lines changed

18 files changed

+405714
-6
lines changed
160 KB
Binary file not shown.

__mocks__/remotes/index.js

Lines changed: 405338 additions & 0 deletions
Large diffs are not rendered by default.

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,8 @@ export interface ProvidesConfig {
9191
* Node modules reconstructed lookup.
9292
*/
9393
nodeModulesReconstructedLookup?: any;
94+
/**
95+
* Original prefix for prefix matches (internal use).
96+
*/
97+
_originalPrefix?: string;
9498
}

packages/enhanced/src/lib/sharing/ConsumeSharedPlugin.ts

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import {
4545
addSingletonFilterWarning,
4646
testRequestFilters,
4747
createLookupKeyForSharing,
48+
extractPathAfterNodeModules,
4849
} from './utils';
4950

5051
const ModuleNotFoundError = require(
@@ -105,6 +106,7 @@ class ConsumeSharedPlugin {
105106
request: key,
106107
include: undefined,
107108
exclude: undefined,
109+
nodeModulesReconstructedLookup: undefined,
108110
}
109111
: // key is a request/key
110112
// item is a version
@@ -123,6 +125,7 @@ class ConsumeSharedPlugin {
123125
request: key,
124126
include: undefined,
125127
exclude: undefined,
128+
nodeModulesReconstructedLookup: undefined,
126129
};
127130
return result;
128131
},
@@ -149,6 +152,7 @@ class ConsumeSharedPlugin {
149152
issuerLayer: item.issuerLayer ? item.issuerLayer : undefined,
150153
layer: item.layer ? item.layer : undefined,
151154
request,
155+
nodeModulesReconstructedLookup: item.nodeModulesReconstructedLookup,
152156
} as ConsumeOptions;
153157
},
154158
);
@@ -496,6 +500,69 @@ class ConsumeSharedPlugin {
496500
);
497501
}
498502

503+
// Then try relative path handling and node_modules paths
504+
let reconstructed: string | null = null;
505+
let modulePathAfterNodeModules: string | null = null;
506+
507+
if (
508+
request &&
509+
!path.isAbsolute(request) &&
510+
RELATIVE_OR_ABSOLUTE_PATH_REGEX.test(request)
511+
) {
512+
reconstructed = path.join(context, request);
513+
modulePathAfterNodeModules =
514+
extractPathAfterNodeModules(reconstructed);
515+
516+
// Try to match with module path after node_modules
517+
if (modulePathAfterNodeModules) {
518+
const moduleMatch =
519+
unresolvedConsumes.get(
520+
createLookupKeyForSharing(
521+
modulePathAfterNodeModules,
522+
contextInfo.issuerLayer,
523+
),
524+
) ||
525+
unresolvedConsumes.get(
526+
createLookupKeyForSharing(
527+
modulePathAfterNodeModules,
528+
undefined,
529+
),
530+
);
531+
532+
if (
533+
moduleMatch !== undefined &&
534+
moduleMatch.nodeModulesReconstructedLookup
535+
) {
536+
return boundCreateConsumeSharedModule(
537+
compilation,
538+
context,
539+
modulePathAfterNodeModules,
540+
moduleMatch,
541+
);
542+
}
543+
}
544+
545+
// Try to match with the full reconstructed path
546+
const reconstructedMatch =
547+
unresolvedConsumes.get(
548+
createLookupKeyForSharing(
549+
reconstructed,
550+
contextInfo.issuerLayer,
551+
),
552+
) ||
553+
unresolvedConsumes.get(
554+
createLookupKeyForSharing(reconstructed, undefined),
555+
);
556+
557+
if (reconstructedMatch !== undefined) {
558+
return boundCreateConsumeSharedModule(
559+
compilation,
560+
context,
561+
reconstructed,
562+
reconstructedMatch,
563+
);
564+
}
565+
}
499566
// Check for prefixed consumes with original request
500567
for (const [prefix, options] of prefixedConsumes) {
501568
const lookup = options.request || prefix;
@@ -538,6 +605,55 @@ class ConsumeSharedPlugin {
538605
}
539606
}
540607

608+
// Also check prefixed consumes with modulePathAfterNodeModules
609+
if (modulePathAfterNodeModules) {
610+
for (const [prefix, options] of prefixedConsumes) {
611+
if (!options.nodeModulesReconstructedLookup) {
612+
continue;
613+
}
614+
// Refined issuerLayer matching logic for reconstructed path
615+
if (options.issuerLayer) {
616+
if (!contextInfo.issuerLayer) {
617+
continue; // Option is layered, request is not: skip
618+
}
619+
if (contextInfo.issuerLayer !== options.issuerLayer) {
620+
continue; // Both are layered but do not match: skip
621+
}
622+
}
623+
// If contextInfo.issuerLayer exists but options.issuerLayer does not, allow (non-layered option matches layered request)
624+
const lookup = options.request || prefix;
625+
if (modulePathAfterNodeModules.startsWith(lookup)) {
626+
const remainder = modulePathAfterNodeModules.slice(
627+
lookup.length,
628+
);
629+
630+
if (
631+
!testRequestFilters(
632+
remainder,
633+
options.include?.request,
634+
options.exclude?.request,
635+
)
636+
) {
637+
continue;
638+
}
639+
640+
return boundCreateConsumeSharedModule(
641+
compilation,
642+
context,
643+
modulePathAfterNodeModules,
644+
{
645+
...options,
646+
import: options.import
647+
? options.import + remainder
648+
: undefined,
649+
shareKey: options.shareKey + remainder,
650+
layer: options.layer,
651+
},
652+
);
653+
}
654+
}
655+
}
656+
541657
return;
542658
});
543659
},

0 commit comments

Comments
 (0)