Skip to content

Commit 4c6d3b1

Browse files
committed
fix(@ngtools/webpack): improve support for multi-option path mapping
1 parent f46a883 commit 4c6d3b1

File tree

1 file changed

+53
-28
lines changed

1 file changed

+53
-28
lines changed

packages/ngtools/webpack/src/paths-plugin.ts

+53-28
Original file line numberDiff line numberDiff line change
@@ -52,36 +52,47 @@ export function resolveWithPaths(
5252
// check if any path mapping rules are relevant
5353
const pathMapOptions = [];
5454
for (const pattern in compilerOptions.paths) {
55-
// can only contain zero or one
56-
const starIndex = pattern.indexOf('*');
57-
if (starIndex === -1) {
58-
if (pattern === originalRequest) {
59-
pathMapOptions.push({
60-
partial: '',
61-
potentials: compilerOptions.paths[pattern],
62-
});
63-
}
64-
} else if (starIndex === 0 && pattern.length === 1) {
55+
// get potentials and remove duplicates; JS Set maintains insertion order
56+
const potentials = Array.from(new Set(compilerOptions.paths[pattern]));
57+
if (potentials.length === 0) {
58+
// no potential replacements so skip
59+
continue;
60+
}
61+
62+
// can only contain zero or one
63+
const starIndex = pattern.indexOf('*');
64+
if (starIndex === -1) {
65+
if (pattern === originalRequest) {
66+
pathMapOptions.push({
67+
starIndex,
68+
partial: '',
69+
potentials,
70+
});
71+
}
72+
} else if (starIndex === 0 && pattern.length === 1) {
73+
pathMapOptions.push({
74+
starIndex,
75+
partial: originalRequest,
76+
potentials,
77+
});
78+
} else if (starIndex === pattern.length - 1) {
79+
if (originalRequest.startsWith(pattern.slice(0, -1))) {
6580
pathMapOptions.push({
66-
partial: originalRequest,
67-
potentials: compilerOptions.paths[pattern],
81+
starIndex,
82+
partial: originalRequest.slice(pattern.length - 1),
83+
potentials,
6884
});
69-
} else if (starIndex === pattern.length - 1) {
70-
if (originalRequest.startsWith(pattern.slice(0, -1))) {
71-
pathMapOptions.push({
72-
partial: originalRequest.slice(pattern.length - 1),
73-
potentials: compilerOptions.paths[pattern],
74-
});
75-
}
76-
} else {
77-
const [prefix, suffix] = pattern.split('*');
78-
if (originalRequest.startsWith(prefix) && originalRequest.endsWith(suffix)) {
79-
pathMapOptions.push({
80-
partial: originalRequest.slice(prefix.length).slice(0, -suffix.length),
81-
potentials: compilerOptions.paths[pattern],
82-
});
83-
}
8485
}
86+
} else {
87+
const [prefix, suffix] = pattern.split('*');
88+
if (originalRequest.startsWith(prefix) && originalRequest.endsWith(suffix)) {
89+
pathMapOptions.push({
90+
starIndex,
91+
partial: originalRequest.slice(prefix.length).slice(0, -suffix.length),
92+
potentials,
93+
});
94+
}
95+
}
8596
}
8697

8798
if (pathMapOptions.length === 0) {
@@ -90,7 +101,18 @@ export function resolveWithPaths(
90101
return;
91102
}
92103

93-
if (pathMapOptions.length === 1 && pathMapOptions[0].potentials.length === 1) {
104+
// exact matches take priority then largest prefix match
105+
pathMapOptions.sort((a, b) => {
106+
if (a.starIndex === -1) {
107+
return -1;
108+
} else if (b.starIndex === -1) {
109+
return 1;
110+
} else {
111+
return b.starIndex - a.starIndex;
112+
}
113+
});
114+
115+
if (pathMapOptions[0].potentials.length === 1) {
94116
const onlyPotential = pathMapOptions[0].potentials[0];
95117
let replacement;
96118
const starIndex = onlyPotential.indexOf('*');
@@ -109,6 +131,9 @@ export function resolveWithPaths(
109131
return;
110132
}
111133

134+
// TODO: The following is used when there is more than one potential and will not be
135+
// needed once this is turned into a full webpack resolver plugin
136+
112137
const moduleResolver = ts.resolveModuleName(
113138
originalRequest,
114139
request.contextInfo.issuer,

0 commit comments

Comments
 (0)