@@ -47,6 +47,7 @@ import {
47
47
createProgram ,
48
48
createCompilerHost ,
49
49
formatDiagnostics ,
50
+ readConfiguration ,
50
51
} from './ngtools_api' ;
51
52
import { findAstNodes } from './transformers/ast_helpers' ;
52
53
@@ -86,13 +87,11 @@ export class AngularCompilerPlugin implements Tapable {
86
87
private _options : AngularCompilerPluginOptions ;
87
88
88
89
// TS compilation.
89
- private _compilerOptions : ts . CompilerOptions ;
90
- private _angularCompilerOptions : CompilerOptions ;
91
- private _tsFilenames : string [ ] ;
90
+ private _compilerOptions : CompilerOptions ;
91
+ private _rootNames : string [ ] ;
92
92
private _program : ( ts . Program | Program ) ;
93
- private _compilerHost : WebpackCompilerHost ;
93
+ private _compilerHost : WebpackCompilerHost & CompilerHost ;
94
94
private _moduleResolutionCache : ts . ModuleResolutionCache ;
95
- private _angularCompilerHost : WebpackCompilerHost & CompilerHost ;
96
95
private _resourceLoader : WebpackResourceLoader ;
97
96
// Contains `moduleImportPath#exportName` => `fullModulePath`.
98
97
private _lazyRoutes : LazyRouteMap = Object . create ( null ) ;
@@ -214,11 +213,10 @@ export class AngularCompilerPlugin implements Tapable {
214
213
}
215
214
216
215
// Parse the tsconfig contents.
217
- const tsConfig = ts . parseJsonConfigFileContent (
218
- tsConfigJson , ts . sys , basePath , undefined , this . _tsConfigPath ) ;
216
+ const config = readConfiguration ( this . _tsConfigPath , tsConfigJson ) ;
219
217
220
- this . _tsFilenames = tsConfig . fileNames ;
221
- this . _compilerOptions = tsConfig . options ;
218
+ this . _rootNames = config . rootNames ;
219
+ this . _compilerOptions = config . options ;
222
220
223
221
// Overwrite outDir so we can find generated files next to their .ts origin in compilerHost.
224
222
this . _compilerOptions . outDir = '' ;
@@ -250,55 +248,54 @@ export class AngularCompilerPlugin implements Tapable {
250
248
// to the webpack dependency tree and rebuilds triggered by file edits.
251
249
this . _compilerOptions . noEmitOnError = false ;
252
250
253
- // Compose Angular Compiler Options.
254
- this . _angularCompilerOptions = Object . assign (
255
- this . _compilerOptions ,
256
- tsConfig . raw [ 'angularCompilerOptions' ] ,
257
- { basePath }
258
- ) ;
259
-
260
251
// Set JIT (no code generation) or AOT mode.
261
252
if ( options . skipCodeGeneration !== undefined ) {
262
253
this . _JitMode = options . skipCodeGeneration ;
263
254
}
264
255
265
256
// Process i18n options.
266
257
if ( options . hasOwnProperty ( 'i18nInFile' ) ) {
267
- this . _angularCompilerOptions . i18nInFile = options . i18nInFile ;
258
+ this . _compilerOptions . i18nInFile = options . i18nInFile ;
268
259
}
269
260
if ( options . hasOwnProperty ( 'i18nInFormat' ) ) {
270
- this . _angularCompilerOptions . i18nInFormat = options . i18nInFormat ;
261
+ this . _compilerOptions . i18nInFormat = options . i18nInFormat ;
271
262
}
272
263
if ( options . hasOwnProperty ( 'i18nOutFile' ) ) {
273
- this . _angularCompilerOptions . i18nOutFile = options . i18nOutFile ;
264
+ this . _compilerOptions . i18nOutFile = options . i18nOutFile ;
274
265
}
275
266
if ( options . hasOwnProperty ( 'i18nOutFormat' ) ) {
276
- this . _angularCompilerOptions . i18nOutFormat = options . i18nOutFormat ;
267
+ this . _compilerOptions . i18nOutFormat = options . i18nOutFormat ;
277
268
}
278
269
if ( options . hasOwnProperty ( 'locale' ) && options . locale ) {
279
- this . _angularCompilerOptions . i18nInLocale = this . _validateLocale ( options . locale ) ;
270
+ this . _compilerOptions . i18nInLocale = this . _validateLocale ( options . locale ) ;
280
271
}
281
272
if ( options . hasOwnProperty ( 'missingTranslation' ) ) {
282
- this . _angularCompilerOptions . i18nInMissingTranslations =
273
+ this . _compilerOptions . i18nInMissingTranslations =
283
274
options . missingTranslation as 'error' | 'warning' | 'ignore' ;
284
275
}
285
276
286
277
// Use entryModule if available in options, otherwise resolve it from mainPath after program
287
278
// creation.
288
279
if ( this . _options . entryModule ) {
289
280
this . _entryModule = this . _options . entryModule ;
290
- } else if ( this . _angularCompilerOptions . entryModule ) {
281
+ } else if ( this . _compilerOptions . entryModule ) {
291
282
this . _entryModule = path . resolve ( this . _basePath ,
292
- this . _angularCompilerOptions . entryModule ) ;
283
+ this . _compilerOptions . entryModule ) ;
293
284
}
294
285
295
286
// Create the webpack compiler host.
296
- this . _compilerHost = new WebpackCompilerHost ( this . _compilerOptions , this . _basePath ) ;
297
- this . _compilerHost . enableCaching ( ) ;
287
+ const webpackCompilerHost = new WebpackCompilerHost ( this . _compilerOptions , this . _basePath ) ;
288
+ webpackCompilerHost . enableCaching ( ) ;
298
289
299
290
// Create and set a new WebpackResourceLoader.
300
291
this . _resourceLoader = new WebpackResourceLoader ( ) ;
301
- this . _compilerHost . setResourceLoader ( this . _resourceLoader ) ;
292
+ webpackCompilerHost . setResourceLoader ( this . _resourceLoader ) ;
293
+
294
+ // Use the WebpackCompilerHost with a resource loader to create an AngularCompilerHost.
295
+ this . _compilerHost = createCompilerHost ( {
296
+ options : this . _compilerOptions ,
297
+ tsHost : webpackCompilerHost
298
+ } ) as CompilerHost & WebpackCompilerHost ;
302
299
303
300
// Override some files in the FileSystem.
304
301
if ( this . _options . hostOverrideFileSystem ) {
@@ -342,28 +339,24 @@ export class AngularCompilerPlugin implements Tapable {
342
339
private _createOrUpdateProgram ( ) {
343
340
return Promise . resolve ( )
344
341
. then ( ( ) => {
345
- const changedTsFiles = this . _getChangedTsFiles ( ) ;
346
-
347
- changedTsFiles . forEach ( ( file ) => {
348
- if ( ! this . _tsFilenames . includes ( file ) ) {
349
- // TODO: figure out if action is needed for files that were removed from the
350
- // compilation.
351
- this . _tsFilenames . push ( file ) ;
352
- }
353
- } ) ;
342
+ // Get the root files from the ts config.
343
+ // When a new root name (like a lazy route) is added, it won't be available from
344
+ // following imports on the existing files, so we need to get the new list of root files.
345
+ this . _rootNames = readConfiguration ( this . _tsConfigPath ) . rootNames ;
354
346
355
- // Update the forked type checker.
347
+ // Update the forked type checker with all changed compilation files.
348
+ // This includes templates, that also need to be reloaded on the type checker.
356
349
if ( this . _forkTypeChecker && ! this . _firstRun ) {
357
- this . _updateForkedTypeChecker ( changedTsFiles ) ;
350
+ this . _updateForkedTypeChecker ( this . _rootNames , this . _getChangedCompilationFiles ( ) ) ;
358
351
}
359
352
360
353
if ( this . _JitMode ) {
361
354
// Create the TypeScript program.
362
355
time ( 'AngularCompilerPlugin._createOrUpdateProgram.ts.createProgram' ) ;
363
356
this . _program = ts . createProgram (
364
- this . _tsFilenames ,
365
- this . _angularCompilerOptions ,
366
- this . _angularCompilerHost ,
357
+ this . _rootNames ,
358
+ this . _compilerOptions ,
359
+ this . _compilerHost ,
367
360
this . _program as ts . Program
368
361
) ;
369
362
timeEnd ( 'AngularCompilerPlugin._createOrUpdateProgram.ts.createProgram' ) ;
@@ -372,26 +365,19 @@ export class AngularCompilerPlugin implements Tapable {
372
365
} else {
373
366
time ( 'AngularCompilerPlugin._createOrUpdateProgram.ng.createProgram' ) ;
374
367
// Create the Angular program.
375
- try {
376
- this . _program = createProgram ( {
377
- rootNames : this . _tsFilenames ,
378
- options : this . _angularCompilerOptions ,
379
- host : this . _angularCompilerHost ,
380
- oldProgram : this . _program as Program
368
+ this . _program = createProgram ( {
369
+ rootNames : this . _rootNames ,
370
+ options : this . _compilerOptions ,
371
+ host : this . _compilerHost ,
372
+ oldProgram : this . _program as Program
373
+ } ) ;
374
+ timeEnd ( 'AngularCompilerPlugin._createOrUpdateProgram.ng.createProgram' ) ;
375
+
376
+ time ( 'AngularCompilerPlugin._createOrUpdateProgram.ng.loadNgStructureAsync' ) ;
377
+ return this . _program . loadNgStructureAsync ( )
378
+ . then ( ( ) => {
379
+ timeEnd ( 'AngularCompilerPlugin._createOrUpdateProgram.ng.loadNgStructureAsync' ) ;
381
380
} ) ;
382
- timeEnd ( 'AngularCompilerPlugin._createOrUpdateProgram.ng.createProgram' ) ;
383
-
384
- time ( 'AngularCompilerPlugin._createOrUpdateProgram.ng.loadNgStructureAsync' ) ;
385
- return this . _program . loadNgStructureAsync ( )
386
- . then ( ( ) => {
387
- timeEnd ( 'AngularCompilerPlugin._createOrUpdateProgram.ng.loadNgStructureAsync' ) ;
388
- } ) ;
389
- } catch ( e ) {
390
- // TODO: remove this when the issue is addressed.
391
- // Temporary workaround for https://github.com/angular/angular/issues/19951
392
- this . _program = undefined ;
393
- throw e ;
394
- }
395
381
}
396
382
} )
397
383
. then ( ( ) => {
@@ -412,7 +398,7 @@ export class AngularCompilerPlugin implements Tapable {
412
398
const result = __NGTOOLS_PRIVATE_API_2 . listLazyRoutes ( {
413
399
program : this . _getTsProgram ( ) ,
414
400
host : this . _compilerHost ,
415
- angularCompilerOptions : Object . assign ( { } , this . _angularCompilerOptions , {
401
+ angularCompilerOptions : Object . assign ( { } , this . _compilerOptions , {
416
402
// genDir seems to still be needed in @angular \compiler-cli\src\compiler_host.js:226.
417
403
genDir : ''
418
404
} ) ,
@@ -508,8 +494,8 @@ export class AngularCompilerPlugin implements Tapable {
508
494
} else {
509
495
// Found a new route, add it to the map and read it into the compiler host.
510
496
this . _lazyRoutes [ moduleKey ] = modulePath ;
511
- this . _angularCompilerHost . readFile ( lazyRouteTSFile ) ;
512
- this . _angularCompilerHost . invalidate ( lazyRouteTSFile ) ;
497
+ this . _compilerHost . readFile ( lazyRouteTSFile ) ;
498
+ this . _compilerHost . invalidate ( lazyRouteTSFile ) ;
513
499
}
514
500
} ) ;
515
501
}
@@ -545,7 +531,7 @@ export class AngularCompilerPlugin implements Tapable {
545
531
546
532
this . _typeCheckerProcess = fork ( path . resolve ( __dirname , typeCheckerFile ) , [ ] , forkOptions ) ;
547
533
this . _typeCheckerProcess . send ( new InitMessage ( this . _compilerOptions , this . _basePath ,
548
- this . _JitMode , this . _tsFilenames ) ) ;
534
+ this . _JitMode , this . _rootNames ) ) ;
549
535
550
536
// Cleanup.
551
537
const killTypeCheckerProcess = ( ) => {
@@ -557,8 +543,8 @@ export class AngularCompilerPlugin implements Tapable {
557
543
process . once ( 'uncaughtException' , killTypeCheckerProcess ) ;
558
544
}
559
545
560
- private _updateForkedTypeChecker ( changedTsFiles : string [ ] ) {
561
- this . _typeCheckerProcess . send ( new UpdateMessage ( changedTsFiles ) ) ;
546
+ private _updateForkedTypeChecker ( rootNames : string [ ] , changedCompilationFiles : string [ ] ) {
547
+ this . _typeCheckerProcess . send ( new UpdateMessage ( rootNames , changedCompilationFiles ) ) ;
562
548
}
563
549
564
550
@@ -682,22 +668,12 @@ export class AngularCompilerPlugin implements Tapable {
682
668
// Update the resource loader with the new webpack compilation.
683
669
this . _resourceLoader . update ( compilation ) ;
684
670
671
+ // Create a new process for the type checker on the second build if there isn't one yet.
672
+ if ( this . _forkTypeChecker && ! this . _firstRun && ! this . _typeCheckerProcess ) {
673
+ this . _createForkedTypeChecker ( ) ;
674
+ }
675
+
685
676
this . _donePromise = Promise . resolve ( )
686
- . then ( ( ) => {
687
- // Create a new process for the type checker.
688
- if ( this . _forkTypeChecker && ! this . _firstRun && ! this . _typeCheckerProcess ) {
689
- this . _createForkedTypeChecker ( ) ;
690
- }
691
- } )
692
- . then ( ( ) => {
693
- if ( this . _firstRun ) {
694
- // Use the WebpackResourceLoader with a resource loader to create an AngularCompilerHost.
695
- this . _angularCompilerHost = createCompilerHost ( {
696
- options : this . _angularCompilerOptions ,
697
- tsHost : this . _compilerHost
698
- } ) as CompilerHost & WebpackCompilerHost ;
699
- }
700
- } )
701
677
. then ( ( ) => this . _update ( ) )
702
678
. then ( ( ) => {
703
679
timeEnd ( 'AngularCompilerPlugin._make' ) ;
@@ -731,10 +707,6 @@ export class AngularCompilerPlugin implements Tapable {
731
707
const changedTsFiles = this . _getChangedTsFiles ( ) ;
732
708
if ( this . _ngCompilerSupportsNewApi ) {
733
709
this . _processLazyRoutes ( this . _listLazyRoutesFromProgram ( ) ) ;
734
- // TODO: remove this when the issue is addressed.
735
- // Fix for a bug in compiler where the program needs to be updated after
736
- // _listLazyRoutesFromProgram is called.
737
- return this . _createOrUpdateProgram ( ) ;
738
710
} else if ( this . _firstRun ) {
739
711
this . _processLazyRoutes ( this . _getLazyRoutesFromNgtools ( ) ) ;
740
712
} else if ( changedTsFiles . length > 0 ) {
@@ -772,11 +744,11 @@ export class AngularCompilerPlugin implements Tapable {
772
744
}
773
745
774
746
// If we have a locale, auto import the locale data file.
775
- if ( this . _angularCompilerOptions . i18nInLocale ) {
747
+ if ( this . _compilerOptions . i18nInLocale ) {
776
748
transformOps . push ( ...registerLocaleData (
777
749
sf ,
778
750
this . entryModule ,
779
- this . _angularCompilerOptions . i18nInLocale
751
+ this . _compilerOptions . i18nInLocale
780
752
) ) ;
781
753
}
782
754
} else if ( this . _platform === PLATFORM . Server ) {
@@ -846,7 +818,7 @@ export class AngularCompilerPlugin implements Tapable {
846
818
}
847
819
848
820
// Write the extracted messages to disk.
849
- const i18nOutFilePath = path . resolve ( this . _basePath , this . _angularCompilerOptions . i18nOutFile ) ;
821
+ const i18nOutFilePath = path . resolve ( this . _basePath , this . _compilerOptions . i18nOutFile ) ;
850
822
const i18nOutFileContent = this . _compilerHost . readFile ( i18nOutFilePath ) ;
851
823
if ( i18nOutFileContent ) {
852
824
_recursiveMkDir ( path . dirname ( i18nOutFilePath ) )
@@ -994,17 +966,14 @@ export class AngularCompilerPlugin implements Tapable {
994
966
995
967
if ( ! hasErrors ( allDiagnostics ) ) {
996
968
time ( 'AngularCompilerPlugin._emit.ng.emit' ) ;
997
- const extractI18n = ! ! this . _angularCompilerOptions . i18nOutFile ;
969
+ const extractI18n = ! ! this . _compilerOptions . i18nOutFile ;
998
970
const emitFlags = extractI18n ? EmitFlags . I18nBundle : EmitFlags . Default ;
999
971
emitResult = angularProgram . emit ( { emitFlags, customTransformers } ) ;
1000
972
allDiagnostics . push ( ...emitResult . diagnostics ) ;
1001
973
if ( extractI18n ) {
1002
974
this . writeI18nOutFile ( ) ;
1003
975
}
1004
976
timeEnd ( 'AngularCompilerPlugin._emit.ng.emit' ) ;
1005
- } else {
1006
- // Throw away the old program if there was an error.
1007
- this . _program = undefined ;
1008
977
}
1009
978
}
1010
979
} catch ( e ) {
0 commit comments