1
1
import * as path from 'path' ;
2
2
import * as ts from 'typescript' ;
3
- import { Callback , Tapable , NormalModuleFactory , NormalModuleFactoryRequest } from './webpack' ;
3
+ import { Request , ResolverPlugin , Callback , Tapable } from './webpack' ;
4
+
5
+
6
+ const ModulesInRootPlugin : new ( a : string , b : string , c : string ) => ResolverPlugin
7
+ = require ( 'enhanced-resolve/lib/ModulesInRootPlugin' ) ;
8
+
9
+ interface CreateInnerCallback {
10
+ ( callback : Callback < any > ,
11
+ options : Callback < any > ,
12
+ message ?: string ,
13
+ messageOptional ?: string ) : Callback < any > ;
14
+ }
15
+
16
+ const createInnerCallback : CreateInnerCallback
17
+ = require ( 'enhanced-resolve/lib/createInnerCallback' ) ;
18
+ const getInnerRequest : ( resolver : ResolverPlugin , request : Request ) => string
19
+ = require ( 'enhanced-resolve/lib/getInnerRequest' ) ;
20
+
4
21
5
22
function escapeRegExp ( str : string ) : string {
6
23
return str . replace ( / [ \- \[ \] \/ \{ \} \( \) \* \+ \? \. \\ \^ \$ \| ] / g, '\\$&' ) ;
7
24
}
8
25
26
+
9
27
export interface PathsPluginOptions {
10
- nmf : NormalModuleFactory ;
11
28
tsConfigPath : string ;
12
29
compilerOptions ?: ts . CompilerOptions ;
13
30
compilerHost ?: ts . CompilerHost ;
14
31
}
15
32
16
33
export class PathsPlugin implements Tapable {
17
- private _nmf : NormalModuleFactory ;
18
34
private _tsConfigPath : string ;
19
35
private _compilerOptions : ts . CompilerOptions ;
20
36
private _host : ts . CompilerHost ;
37
+
38
+ source : string ;
39
+ target : string ;
40
+
41
+ private mappings : any ;
42
+
21
43
private _absoluteBaseUrl : string ;
22
- private _mappings : any [ ] = [ ] ;
23
44
24
45
private static _loadOptionsFromTsConfig ( tsConfigPath : string , host ?: ts . CompilerHost ) :
25
46
ts . CompilerOptions {
@@ -55,13 +76,15 @@ export class PathsPlugin implements Tapable {
55
76
this . _host = ts . createCompilerHost ( this . _compilerOptions , false ) ;
56
77
}
57
78
79
+ this . source = 'described-resolve' ;
80
+ this . target = 'resolve' ;
81
+
58
82
this . _absoluteBaseUrl = path . resolve (
59
83
path . dirname ( this . _tsConfigPath ) ,
60
84
this . _compilerOptions . baseUrl || '.'
61
85
) ;
62
86
63
- this . _nmf = options . nmf ;
64
-
87
+ this . mappings = [ ] ;
65
88
let paths = this . _compilerOptions . paths || { } ;
66
89
Object . keys ( paths ) . forEach ( alias => {
67
90
let onlyModule = alias . indexOf ( '*' ) === - 1 ;
@@ -76,7 +99,7 @@ export class PathsPlugin implements Tapable {
76
99
aliasPattern = new RegExp ( `^${ withStarCapturing } ` ) ;
77
100
}
78
101
79
- this . _mappings . push ( {
102
+ this . mappings . push ( {
80
103
onlyModule,
81
104
alias,
82
105
aliasPattern,
@@ -86,36 +109,66 @@ export class PathsPlugin implements Tapable {
86
109
} ) ;
87
110
}
88
111
89
- apply ( ) : void {
90
- this . _nmf . plugin ( 'before-resolve' , ( request : NormalModuleFactoryRequest ,
91
- callback : Callback < any > ) => {
92
- for ( let mapping of this . _mappings ) {
93
- const match = request . request . match ( mapping . aliasPattern ) ;
94
- if ( ! match ) { continue ; }
112
+ apply ( resolver : ResolverPlugin ) : void {
113
+ let baseUrl = this . _compilerOptions . baseUrl || '.' ;
95
114
96
- let newRequestStr = mapping . target ;
97
- if ( ! mapping . onlyModule ) {
98
- newRequestStr = newRequestStr . replace ( '*' , match [ 1 ] ) ;
99
- }
100
-
101
- const moduleResolver : ts . ResolvedModuleWithFailedLookupLocations =
102
- ts . nodeModuleNameResolver (
103
- newRequestStr ,
104
- this . _absoluteBaseUrl ,
105
- this . _compilerOptions ,
106
- this . _host
107
- ) ;
108
- const moduleFilePath = moduleResolver . resolvedModule ?
109
- moduleResolver . resolvedModule . resolvedFileName : '' ;
110
-
111
- if ( moduleFilePath ) {
112
- return callback ( null , Object . assign ( { } , request , {
113
- request : moduleFilePath . includes ( '.d.ts' ) ? newRequestStr : moduleFilePath
114
- } ) ) ;
115
- }
116
- }
115
+ if ( baseUrl ) {
116
+ resolver . apply ( new ModulesInRootPlugin ( 'module' , this . _absoluteBaseUrl , 'resolve' ) ) ;
117
+ }
117
118
118
- return callback ( null , request ) ;
119
+ this . mappings . forEach ( ( mapping : any ) => {
120
+ resolver . plugin ( this . source , this . createPlugin ( resolver , mapping ) ) ;
119
121
} ) ;
120
122
}
123
+
124
+ resolve ( resolver : ResolverPlugin , mapping : any , request : any , callback : Callback < any > ) : any {
125
+ let innerRequest = getInnerRequest ( resolver , request ) ;
126
+ if ( ! innerRequest ) {
127
+ return callback ( ) ;
128
+ }
129
+
130
+ let match = innerRequest . match ( mapping . aliasPattern ) ;
131
+ if ( ! match ) {
132
+ return callback ( ) ;
133
+ }
134
+
135
+ let newRequestStr = mapping . target ;
136
+ if ( ! mapping . onlyModule ) {
137
+ newRequestStr = newRequestStr . replace ( '*' , match [ 1 ] ) ;
138
+ }
139
+ if ( newRequestStr [ 0 ] === '.' ) {
140
+ newRequestStr = path . resolve ( this . _absoluteBaseUrl , newRequestStr ) ;
141
+ }
142
+
143
+ let newRequest = Object . assign ( { } , request , {
144
+ request : newRequestStr
145
+ } ) as Request ;
146
+
147
+ return resolver . doResolve (
148
+ this . target ,
149
+ newRequest ,
150
+ `aliased with mapping '${ innerRequest } ': '${ mapping . alias } ' to '${ newRequestStr } '` ,
151
+ createInnerCallback (
152
+ function ( err , result ) {
153
+ if ( arguments . length > 0 ) {
154
+ return callback ( err , result ) ;
155
+ }
156
+
157
+ // don't allow other aliasing or raw request
158
+ callback ( null , null ) ;
159
+ } ,
160
+ callback
161
+ )
162
+ ) ;
163
+ }
164
+
165
+ createPlugin ( resolver : ResolverPlugin , mapping : any ) : any {
166
+ return ( request : any , callback : Callback < any > ) => {
167
+ try {
168
+ this . resolve ( resolver , mapping , request , callback ) ;
169
+ } catch ( err ) {
170
+ callback ( err ) ;
171
+ }
172
+ } ;
173
+ }
121
174
}
0 commit comments