@@ -13,19 +13,47 @@ import {
1313const ModulesInRootPlugin : new ( a : string , b : string , c : string ) => ResolverPlugin
1414 = require ( 'enhanced-resolve/lib/ModulesInRootPlugin' ) ;
1515
16- export interface Mapping {
17- onlyModule : boolean ;
18- alias : string ;
19- aliasPattern : RegExp ;
20- target : string ;
21- }
16+ export function resolveWithPaths (
17+ request : NormalModuleFactoryRequest ,
18+ callback : Callback < NormalModuleFactoryRequest > ,
19+ compilerOptions : ts . CompilerOptions ,
20+ host : ts . CompilerHost ,
21+ cache ?: ts . ModuleResolutionCache ,
22+ ) {
23+ if ( ! request ) {
24+ callback ( null , request ) ;
25+ return ;
26+ }
27+
28+ // Only work on Javascript/TypeScript issuers.
29+ if ( ! request . contextInfo . issuer || ! request . contextInfo . issuer . match ( / \. [ j t ] s $ / ) ) {
30+ callback ( null , request ) ;
31+ return ;
32+ }
2233
34+ const moduleResolver = ts . resolveModuleName (
35+ request . request ,
36+ request . contextInfo . issuer ,
37+ compilerOptions ,
38+ host ,
39+ cache
40+ ) ;
41+
42+ let moduleFilePath = moduleResolver . resolvedModule
43+ && moduleResolver . resolvedModule . resolvedFileName ;
44+
45+ // If TypeScript gives us a .d.ts it's probably a node module and we need to let webpack
46+ // do the resolution.
47+ if ( moduleFilePath ) {
48+ moduleFilePath = moduleFilePath . replace ( / \. d \. t s $ / , '.js' ) ;
49+ if ( host . fileExists ( moduleFilePath ) ) {
50+ request . request = moduleFilePath ;
51+ }
52+ }
2353
24- function escapeRegExp ( str : string ) : string {
25- return str . replace ( / [ \- \[ \] \/ \{ \} \( \) \* \+ \? \. \\ \^ \$ \| ] / g, '\\$&' ) ;
54+ callback ( null , request ) ;
2655}
2756
28-
2957export interface PathsPluginOptions {
3058 nmf : NormalModuleFactory ;
3159 tsConfigPath : string ;
@@ -35,15 +63,11 @@ export interface PathsPluginOptions {
3563
3664export class PathsPlugin implements Tapable {
3765 private _nmf : NormalModuleFactory ;
38- private _tsConfigPath : string ;
3966 private _compilerOptions : ts . CompilerOptions ;
4067 private _host : ts . CompilerHost ;
4168
4269 source : string ;
4370 target : string ;
44-
45- private _mappings : Mapping [ ] ;
46-
4771 private _absoluteBaseUrl : string ;
4872
4973 private static _loadOptionsFromTsConfig ( tsConfigPath : string , host ?: ts . CompilerHost ) :
@@ -66,12 +90,12 @@ export class PathsPlugin implements Tapable {
6690 // This could happen in JavaScript.
6791 throw new Error ( 'tsConfigPath option is mandatory.' ) ;
6892 }
69- this . _tsConfigPath = options . tsConfigPath ;
93+ const tsConfigPath = options . tsConfigPath ;
7094
7195 if ( options . compilerOptions ) {
7296 this . _compilerOptions = options . compilerOptions ;
7397 } else {
74- this . _compilerOptions = PathsPlugin . _loadOptionsFromTsConfig ( this . _tsConfigPath ) ;
98+ this . _compilerOptions = PathsPlugin . _loadOptionsFromTsConfig ( tsConfigPath ) ;
7599 }
76100
77101 if ( options . compilerHost ) {
@@ -85,33 +109,9 @@ export class PathsPlugin implements Tapable {
85109 this . target = 'resolve' ;
86110
87111 this . _absoluteBaseUrl = path . resolve (
88- path . dirname ( this . _tsConfigPath ) ,
112+ path . dirname ( tsConfigPath ) ,
89113 this . _compilerOptions . baseUrl || '.'
90114 ) ;
91-
92- this . _mappings = [ ] ;
93- let paths = this . _compilerOptions . paths || { } ;
94- Object . keys ( paths ) . forEach ( alias => {
95- let onlyModule = alias . indexOf ( '*' ) === - 1 ;
96- let excapedAlias = escapeRegExp ( alias ) ;
97- let targets = paths [ alias ] ;
98- targets . forEach ( target => {
99- let aliasPattern : RegExp ;
100- if ( onlyModule ) {
101- aliasPattern = new RegExp ( `^${ excapedAlias } $` ) ;
102- } else {
103- let withStarCapturing = excapedAlias . replace ( '\\*' , '(.*)' ) ;
104- aliasPattern = new RegExp ( `^${ withStarCapturing } ` ) ;
105- }
106-
107- this . _mappings . push ( {
108- onlyModule,
109- alias,
110- aliasPattern,
111- target : target
112- } ) ;
113- } ) ;
114- } ) ;
115115 }
116116
117117 apply ( resolver : ResolverPlugin ) : void {
@@ -121,43 +121,8 @@ export class PathsPlugin implements Tapable {
121121 resolver . apply ( new ModulesInRootPlugin ( 'module' , this . _absoluteBaseUrl , 'resolve' ) ) ;
122122 }
123123
124- this . _nmf . plugin ( 'before-resolve' , ( request : NormalModuleFactoryRequest ,
125- callback : Callback < any > ) => {
126- // Only work on TypeScript issuers.
127- if ( ! request . contextInfo . issuer || ! request . contextInfo . issuer . match ( / \. [ j t ] s $ / ) ) {
128- return callback ( null , request ) ;
129- }
130-
131- for ( let mapping of this . _mappings ) {
132- const match = request . request . match ( mapping . aliasPattern ) ;
133- if ( ! match ) { continue ; }
134- let newRequestStr = mapping . target ;
135- if ( ! mapping . onlyModule ) {
136- newRequestStr = newRequestStr . replace ( '*' , match [ 1 ] ) ;
137- }
138- const moduleResolver = ts . resolveModuleName (
139- request . request ,
140- request . contextInfo . issuer ,
141- this . _compilerOptions ,
142- this . _host
143- ) ;
144- let moduleFilePath = moduleResolver . resolvedModule
145- && moduleResolver . resolvedModule . resolvedFileName ;
146-
147- // If TypeScript gives us a .d.ts it's probably a node module and we need to let webpack
148- // do the resolution.
149- if ( moduleFilePath && moduleFilePath . endsWith ( '.d.ts' ) ) {
150- moduleFilePath = moduleFilePath . replace ( / \. d \. t s $ / , '.js' ) ;
151- if ( ! this . _host . fileExists ( moduleFilePath ) ) {
152- continue ;
153- }
154- }
155- if ( moduleFilePath ) {
156- return callback ( null , Object . assign ( { } , request , { request : moduleFilePath } ) ) ;
157- }
158- }
159-
160- return callback ( null , request ) ;
124+ this . _nmf . plugin ( 'before-resolve' , ( request , callback ) => {
125+ resolveWithPaths ( request , callback , this . _compilerOptions , this . _host ) ;
161126 } ) ;
162127 }
163128}
0 commit comments