@@ -52,36 +52,47 @@ export function resolveWithPaths(
52
52
// check if any path mapping rules are relevant
53
53
const pathMapOptions = [ ] ;
54
54
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 ) ) ) {
65
80
pathMapOptions . push ( {
66
- partial : originalRequest ,
67
- potentials : compilerOptions . paths [ pattern ] ,
81
+ starIndex,
82
+ partial : originalRequest . slice ( pattern . length - 1 ) ,
83
+ potentials,
68
84
} ) ;
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
- }
84
85
}
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
+ }
85
96
}
86
97
87
98
if ( pathMapOptions . length === 0 ) {
@@ -90,7 +101,18 @@ export function resolveWithPaths(
90
101
return ;
91
102
}
92
103
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 ) {
94
116
const onlyPotential = pathMapOptions [ 0 ] . potentials [ 0 ] ;
95
117
let replacement ;
96
118
const starIndex = onlyPotential . indexOf ( '*' ) ;
@@ -109,6 +131,9 @@ export function resolveWithPaths(
109
131
return ;
110
132
}
111
133
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
+
112
137
const moduleResolver = ts . resolveModuleName (
113
138
originalRequest ,
114
139
request . contextInfo . issuer ,
0 commit comments