@@ -28,24 +28,25 @@ const dev = Math.floor(Math.random() * 10000);
2828
2929export class WebpackCompilerHost implements ts . CompilerHost {
3030 private _syncHost : virtualFs . SyncDelegateHost ;
31+ private _memoryHost : virtualFs . SyncDelegateHost ;
3132 private _changedFiles = new Set < string > ( ) ;
3233 private _basePath : Path ;
3334 private _resourceLoader ?: WebpackResourceLoader ;
35+ private _sourceFileCache = new Map < string , ts . SourceFile > ( ) ;
3436
3537 constructor (
3638 private _options : ts . CompilerOptions ,
3739 basePath : string ,
3840 host : virtualFs . Host ,
3941 ) {
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 ( ) ) ;
4144 this . _basePath = normalize ( basePath ) ;
4245 }
4346
4447 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 { } as { _cache : Map < Path , { } > } )
49+ . _cache . keys ( ) ] ;
4950 }
5051
5152 denormalizePath ( path : string ) {
@@ -79,35 +80,50 @@ export class WebpackCompilerHost implements ts.CompilerHost {
7980 invalidate ( fileName : string ) : void {
8081 const fullPath = this . resolve ( fileName ) ;
8182
82- if ( this . fileExists ( fileName ) ) {
83- this . _changedFiles . add ( fullPath ) ;
83+ if ( this . _memoryHost . exists ( fullPath ) ) {
84+ this . _memoryHost . delete ( fullPath ) ;
8485 }
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 { }
8595 }
8696
8797 fileExists ( fileName : string , delegate = true ) : boolean {
8898 const p = this . resolve ( fileName ) ;
8999
100+ if ( this . _memoryHost . isFile ( p ) ) {
101+ return true ;
102+ }
103+
104+ if ( ! delegate ) {
105+ return false ;
106+ }
107+
108+ let exists = false ;
90109 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 ) ;
101111 } catch { }
102112
103- return false ;
113+ return exists ;
104114 }
105115
106116 readFile ( fileName : string ) : string | undefined {
107117 const filePath = this . resolve ( fileName ) ;
108118
109119 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+ }
111127 } catch {
112128 return undefined ;
113129 }
@@ -116,7 +132,13 @@ export class WebpackCompilerHost implements ts.CompilerHost {
116132 readFileBuffer ( fileName : string ) : Buffer {
117133 const filePath = this . resolve ( fileName ) ;
118134
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+ }
120142 }
121143
122144 private _makeStats ( stats : virtualFs . Stats < Partial < Stats > > ) : Stats {
@@ -154,7 +176,7 @@ export class WebpackCompilerHost implements ts.CompilerHost {
154176
155177 let stats : virtualFs . Stats < Partial < Stats > > | Stats | null = null ;
156178 try {
157- stats = this . _syncHost . stat ( p ) ;
179+ stats = this . _memoryHost . stat ( p ) || this . _syncHost . stat ( p ) ;
158180 } catch { }
159181
160182 if ( ! stats ) {
@@ -172,7 +194,7 @@ export class WebpackCompilerHost implements ts.CompilerHost {
172194 const p = this . resolve ( directoryName ) ;
173195
174196 try {
175- return this . _syncHost . isDirectory ( p ) ;
197+ return this . _memoryHost . isDirectory ( p ) || this . _syncHost . isDirectory ( p ) ;
176198 } catch {
177199 return false ;
178200 }
@@ -194,14 +216,37 @@ export class WebpackCompilerHost implements ts.CompilerHost {
194216 delegated = [ ] ;
195217 }
196218
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 ] ) ] ;
198233 }
199234
200235 getSourceFile ( fileName : string , languageVersion : ts . ScriptTarget , onError ?: OnErrorFn ) {
236+ const p = this . resolve ( fileName ) ;
237+
201238 try {
239+ const cached = this . _sourceFileCache . get ( p ) ;
240+ if ( cached ) {
241+ return cached ;
242+ }
243+
202244 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 ;
205250 }
206251 } catch ( e ) {
207252 if ( onError ) {
@@ -229,7 +274,7 @@ export class WebpackCompilerHost implements ts.CompilerHost {
229274 const p = this . resolve ( fileName ) ;
230275
231276 try {
232- this . _syncHost . write ( p , virtualFs . stringToFileBuffer ( data ) ) ;
277+ this . _memoryHost . write ( p , virtualFs . stringToFileBuffer ( data ) ) ;
233278 } catch ( e ) {
234279 if ( onError ) {
235280 onError ( e . message ) ;
0 commit comments