11import * as path from 'path' ;
22import * 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+
421
522function escapeRegExp ( str : string ) : string {
623 return str . replace ( / [ \- \[ \] \/ \{ \} \( \) \* \+ \? \. \\ \^ \$ \| ] / g, '\\$&' ) ;
724}
825
26+
927export interface PathsPluginOptions {
10- nmf : NormalModuleFactory ;
1128 tsConfigPath : string ;
1229 compilerOptions ?: ts . CompilerOptions ;
1330 compilerHost ?: ts . CompilerHost ;
1431}
1532
1633export class PathsPlugin implements Tapable {
17- private _nmf : NormalModuleFactory ;
1834 private _tsConfigPath : string ;
1935 private _compilerOptions : ts . CompilerOptions ;
2036 private _host : ts . CompilerHost ;
37+
38+ source : string ;
39+ target : string ;
40+
41+ private mappings : any ;
42+
2143 private _absoluteBaseUrl : string ;
22- private _mappings : any [ ] = [ ] ;
2344
2445 private static _loadOptionsFromTsConfig ( tsConfigPath : string , host ?: ts . CompilerHost ) :
2546 ts . CompilerOptions {
@@ -55,13 +76,15 @@ export class PathsPlugin implements Tapable {
5576 this . _host = ts . createCompilerHost ( this . _compilerOptions , false ) ;
5677 }
5778
79+ this . source = 'described-resolve' ;
80+ this . target = 'resolve' ;
81+
5882 this . _absoluteBaseUrl = path . resolve (
5983 path . dirname ( this . _tsConfigPath ) ,
6084 this . _compilerOptions . baseUrl || '.'
6185 ) ;
6286
63- this . _nmf = options . nmf ;
64-
87+ this . mappings = [ ] ;
6588 let paths = this . _compilerOptions . paths || { } ;
6689 Object . keys ( paths ) . forEach ( alias => {
6790 let onlyModule = alias . indexOf ( '*' ) === - 1 ;
@@ -76,7 +99,7 @@ export class PathsPlugin implements Tapable {
7699 aliasPattern = new RegExp ( `^${ withStarCapturing } ` ) ;
77100 }
78101
79- this . _mappings . push ( {
102+ this . mappings . push ( {
80103 onlyModule,
81104 alias,
82105 aliasPattern,
@@ -86,36 +109,66 @@ export class PathsPlugin implements Tapable {
86109 } ) ;
87110 }
88111
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 || '.' ;
95114
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+ }
117118
118- return callback ( null , request ) ;
119+ this . mappings . forEach ( ( mapping : any ) => {
120+ resolver . plugin ( this . source , this . createPlugin ( resolver , mapping ) ) ;
119121 } ) ;
120122 }
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+ }
121174}
0 commit comments