@@ -28,24 +28,25 @@ const dev = Math.floor(Math.random() * 10000);
28
28
29
29
export class WebpackCompilerHost implements ts . CompilerHost {
30
30
private _syncHost : virtualFs . SyncDelegateHost ;
31
+ private _memoryHost : virtualFs . SyncDelegateHost ;
31
32
private _changedFiles = new Set < string > ( ) ;
32
33
private _basePath : Path ;
33
34
private _resourceLoader ?: WebpackResourceLoader ;
35
+ private _sourceFileCache = new Map < string , ts . SourceFile > ( ) ;
34
36
35
37
constructor (
36
38
private _options : ts . CompilerOptions ,
37
39
basePath : string ,
38
40
host : virtualFs . Host ,
39
41
) {
40
- this . _syncHost = new virtualFs . SyncDelegateHost ( new virtualFs . CordHost ( host ) ) ;
42
+ this . _syncHost = new virtualFs . SyncDelegateHost ( host ) ;
43
+ this . _memoryHost = new virtualFs . SyncDelegateHost ( new virtualFs . SimpleMemoryHost ( ) ) ;
41
44
this . _basePath = normalize ( basePath ) ;
42
45
}
43
46
44
47
private get virtualFiles ( ) : Path [ ] {
45
- return ( this . _syncHost . delegate as virtualFs . CordHost )
46
- . records ( )
47
- . filter ( record => record . kind === 'create' )
48
- . map ( ( record : virtualFs . CordHostCreate ) => record . path ) ;
48
+ return [ ...( this . _memoryHost . delegate as unknown as { _cache : Map < Path , { } > } )
49
+ . _cache . keys ( ) ] ;
49
50
}
50
51
51
52
denormalizePath ( path : string ) {
@@ -79,35 +80,50 @@ export class WebpackCompilerHost implements ts.CompilerHost {
79
80
invalidate ( fileName : string ) : void {
80
81
const fullPath = this . resolve ( fileName ) ;
81
82
82
- if ( this . fileExists ( fileName ) ) {
83
- this . _changedFiles . add ( fullPath ) ;
83
+ if ( this . _memoryHost . exists ( fullPath ) ) {
84
+ this . _memoryHost . delete ( fullPath ) ;
84
85
}
86
+
87
+ this . _sourceFileCache . delete ( fullPath ) ;
88
+
89
+ try {
90
+ const exists = this . _syncHost . isFile ( fullPath ) ;
91
+ if ( exists ) {
92
+ this . _changedFiles . add ( fullPath ) ;
93
+ }
94
+ } catch { }
85
95
}
86
96
87
97
fileExists ( fileName : string , delegate = true ) : boolean {
88
98
const p = this . resolve ( fileName ) ;
89
99
100
+ if ( this . _memoryHost . isFile ( p ) ) {
101
+ return true ;
102
+ }
103
+
104
+ if ( ! delegate ) {
105
+ return false ;
106
+ }
107
+
108
+ let exists = false ;
90
109
try {
91
- const exists = this . _syncHost . isFile ( p ) ;
92
- if ( delegate ) {
93
- return exists ;
94
- } else if ( exists ) {
95
- const backend = new virtualFs . SyncDelegateHost (
96
- ( this . _syncHost . delegate as virtualFs . CordHost ) . backend as virtualFs . Host ,
97
- ) ;
98
-
99
- return ! backend . isFile ( p ) ;
100
- }
110
+ exists = this . _syncHost . isFile ( p ) ;
101
111
} catch { }
102
112
103
- return false ;
113
+ return exists ;
104
114
}
105
115
106
116
readFile ( fileName : string ) : string | undefined {
107
117
const filePath = this . resolve ( fileName ) ;
108
118
109
119
try {
110
- return virtualFs . fileBufferToString ( this . _syncHost . read ( filePath ) ) ;
120
+ if ( this . _memoryHost . isFile ( filePath ) ) {
121
+ return virtualFs . fileBufferToString ( this . _memoryHost . read ( filePath ) ) ;
122
+ } else {
123
+ const content = this . _syncHost . read ( filePath ) ;
124
+
125
+ return virtualFs . fileBufferToString ( content ) ;
126
+ }
111
127
} catch {
112
128
return undefined ;
113
129
}
@@ -116,7 +132,13 @@ export class WebpackCompilerHost implements ts.CompilerHost {
116
132
readFileBuffer ( fileName : string ) : Buffer {
117
133
const filePath = this . resolve ( fileName ) ;
118
134
119
- return Buffer . from ( this . _syncHost . read ( filePath ) ) ;
135
+ if ( this . _memoryHost . isFile ( filePath ) ) {
136
+ return Buffer . from ( this . _memoryHost . read ( filePath ) ) ;
137
+ } else {
138
+ const content = this . _syncHost . read ( filePath ) ;
139
+
140
+ return Buffer . from ( content ) ;
141
+ }
120
142
}
121
143
122
144
private _makeStats ( stats : virtualFs . Stats < Partial < Stats > > ) : Stats {
@@ -154,7 +176,7 @@ export class WebpackCompilerHost implements ts.CompilerHost {
154
176
155
177
let stats : virtualFs . Stats < Partial < Stats > > | Stats | null = null ;
156
178
try {
157
- stats = this . _syncHost . stat ( p ) ;
179
+ stats = this . _memoryHost . stat ( p ) || this . _syncHost . stat ( p ) ;
158
180
} catch { }
159
181
160
182
if ( ! stats ) {
@@ -172,7 +194,7 @@ export class WebpackCompilerHost implements ts.CompilerHost {
172
194
const p = this . resolve ( directoryName ) ;
173
195
174
196
try {
175
- return this . _syncHost . isDirectory ( p ) ;
197
+ return this . _memoryHost . isDirectory ( p ) || this . _syncHost . isDirectory ( p ) ;
176
198
} catch {
177
199
return false ;
178
200
}
@@ -194,14 +216,37 @@ export class WebpackCompilerHost implements ts.CompilerHost {
194
216
delegated = [ ] ;
195
217
}
196
218
197
- return delegated ;
219
+ let memory : string [ ] ;
220
+ try {
221
+ memory = this . _memoryHost . list ( p ) . filter ( x => {
222
+ try {
223
+ return this . _memoryHost . isDirectory ( join ( p , x ) ) ;
224
+ } catch {
225
+ return false ;
226
+ }
227
+ } ) ;
228
+ } catch {
229
+ memory = [ ] ;
230
+ }
231
+
232
+ return [ ...new Set ( [ ...delegated , ...memory ] ) ] ;
198
233
}
199
234
200
235
getSourceFile ( fileName : string , languageVersion : ts . ScriptTarget , onError ?: OnErrorFn ) {
236
+ const p = this . resolve ( fileName ) ;
237
+
201
238
try {
239
+ const cached = this . _sourceFileCache . get ( p ) ;
240
+ if ( cached ) {
241
+ return cached ;
242
+ }
243
+
202
244
const content = this . readFile ( fileName ) ;
203
- if ( content != undefined ) {
204
- return ts . createSourceFile ( workaroundResolve ( fileName ) , content , languageVersion , true ) ;
245
+ if ( content !== undefined ) {
246
+ const sf = ts . createSourceFile ( workaroundResolve ( fileName ) , content , languageVersion , true ) ;
247
+ this . _sourceFileCache . set ( p , sf ) ;
248
+
249
+ return sf ;
205
250
}
206
251
} catch ( e ) {
207
252
if ( onError ) {
@@ -229,7 +274,7 @@ export class WebpackCompilerHost implements ts.CompilerHost {
229
274
const p = this . resolve ( fileName ) ;
230
275
231
276
try {
232
- this . _syncHost . write ( p , virtualFs . stringToFileBuffer ( data ) ) ;
277
+ this . _memoryHost . write ( p , virtualFs . stringToFileBuffer ( data ) ) ;
233
278
} catch ( e ) {
234
279
if ( onError ) {
235
280
onError ( e . message ) ;
0 commit comments