@@ -103,6 +103,11 @@ export interface AngularCompilerPluginOptions {
103
103
nameLazyFiles ?: boolean ;
104
104
logger ?: logging . Logger ;
105
105
directTemplateLoading ?: boolean ;
106
+ // When using the loadChildren string syntax, @ngtools/webpack must query @angular/compiler-cli
107
+ // via a private API to know which lazy routes exist. This increases build and rebuild time.
108
+ // When using Ivy, the string syntax is not supported at all. Thus we shouldn't attempt that.
109
+ // This option is also used for when the compilation doesn't need this sort of processing at all.
110
+ discoverLazyRoutes ?: boolean ;
106
111
107
112
// added to the list of lazy routes
108
113
additionalLazyModules ?: { [ module : string ] : string } ;
@@ -134,6 +139,7 @@ export class AngularCompilerPlugin {
134
139
private _compilerHost : WebpackCompilerHost & CompilerHost ;
135
140
private _moduleResolutionCache : ts . ModuleResolutionCache ;
136
141
private _resourceLoader ?: WebpackResourceLoader ;
142
+ private _discoverLazyRoutes = true ;
137
143
// Contains `moduleImportPath#exportName` => `fullModulePath`.
138
144
private _lazyRoutes : LazyRouteMap = { } ;
139
145
private _tsConfigPath : string ;
@@ -292,6 +298,26 @@ export class AngularCompilerPlugin {
292
298
this . _platformTransformers = options . platformTransformers ;
293
299
}
294
300
301
+ if ( options . discoverLazyRoutes !== undefined ) {
302
+ this . _discoverLazyRoutes = options . discoverLazyRoutes ;
303
+ }
304
+
305
+ if ( this . _discoverLazyRoutes === false && this . options . additionalLazyModuleResources
306
+ && this . options . additionalLazyModuleResources . length > 0 ) {
307
+ this . _warnings . push (
308
+ new Error ( `Lazy route discovery is disabled but additional Lazy Module Resources were`
309
+ + ` provided. These will be ignored.` ) ,
310
+ ) ;
311
+ }
312
+
313
+ if ( this . _discoverLazyRoutes === false && this . options . additionalLazyModules
314
+ && Object . keys ( this . options . additionalLazyModules ) . length > 0 ) {
315
+ this . _warnings . push (
316
+ new Error ( `Lazy route discovery is disabled but additional lazy modules were provided.`
317
+ + `These will be ignored.` ) ,
318
+ ) ;
319
+ }
320
+
295
321
// Default ContextElementDependency to the one we can import from here.
296
322
// Failing to use the right ContextElementDependency will throw the error below:
297
323
// "No module factory available for dependency type: ContextElementDependency"
@@ -411,7 +437,7 @@ export class AngularCompilerPlugin {
411
437
this . _entryModule = resolveEntryModuleFromMain (
412
438
this . _mainPath , this . _compilerHost , this . _getTsProgram ( ) as ts . Program ) ;
413
439
414
- if ( ! this . entryModule && ! this . _compilerOptions . enableIvy ) {
440
+ if ( this . _discoverLazyRoutes && ! this . entryModule && ! this . _compilerOptions . enableIvy ) {
415
441
this . _warnings . push ( 'Lazy routes discovery is not enabled. '
416
442
+ 'Because there is neither an entryModule nor a '
417
443
+ 'statically analyzable bootstrap code in the main file.' ,
@@ -697,64 +723,66 @@ export class AngularCompilerPlugin {
697
723
) ;
698
724
} ) ;
699
725
700
- // Add lazy modules to the context module for @angular /core
701
- compiler . hooks . contextModuleFactory . tap ( 'angular-compiler' , cmf => {
702
- const angularCorePackagePath = require . resolve ( '@angular/core/package.json' ) ;
703
-
704
- // APFv6 does not have single FESM anymore. Instead of verifying if we're pointing to
705
- // FESMs, we resolve the `@angular/core` path and verify that the path for the
706
- // module starts with it.
707
- // This may be slower but it will be compatible with both APF5, 6 and potential future
708
- // versions (until the dynamic import appears outside of core I suppose).
709
- // We resolve any symbolic links in order to get the real path that would be used in webpack.
710
- const angularCoreResourceRoot = fs . realpathSync ( path . dirname ( angularCorePackagePath ) ) ;
711
-
712
- cmf . hooks . afterResolve . tapPromise ( 'angular-compiler' , async result => {
713
- // Alter only existing request from Angular or one of the additional lazy module resources.
714
- const isLazyModuleResource = ( resource : string ) =>
715
- resource . startsWith ( angularCoreResourceRoot ) ||
716
- ( this . options . additionalLazyModuleResources &&
717
- this . options . additionalLazyModuleResources . includes ( resource ) ) ;
718
-
719
- if ( ! result || ! this . done || ! isLazyModuleResource ( result . resource ) ) {
720
- return result ;
721
- }
722
-
723
- return this . done . then (
724
- ( ) => {
725
- // This folder does not exist, but we need to give webpack a resource.
726
- // TODO: check if we can't just leave it as is (angularCoreModuleDir).
727
- result . resource = path . join ( this . _basePath , '$$_lazy_route_resource' ) ;
728
- // tslint:disable-next-line:no-any
729
- result . dependencies . forEach ( ( d : any ) => d . critical = false ) ;
730
- // tslint:disable-next-line:no-any
731
- result . resolveDependencies = ( _fs : any , options : any , callback : Callback ) => {
732
- const dependencies = Object . keys ( this . _lazyRoutes )
733
- . map ( ( key ) => {
734
- const modulePath = this . _lazyRoutes [ key ] ;
735
- if ( modulePath !== null ) {
736
- const name = key . split ( '#' ) [ 0 ] ;
737
-
738
- return new this . _contextElementDependencyConstructor ( modulePath , name ) ;
739
- } else {
740
- return null ;
741
- }
742
- } )
743
- . filter ( x => ! ! x ) ;
744
-
745
- if ( this . _options . nameLazyFiles ) {
746
- options . chunkName = '[request]' ;
747
- }
748
-
749
- callback ( null , dependencies ) ;
750
- } ;
751
-
726
+ if ( this . _discoverLazyRoutes ) {
727
+ // Add lazy modules to the context module for @angular /core
728
+ compiler . hooks . contextModuleFactory . tap ( 'angular-compiler' , cmf => {
729
+ const angularCorePackagePath = require . resolve ( '@angular/core/package.json' ) ;
730
+
731
+ // APFv6 does not have single FESM anymore. Instead of verifying if we're pointing to
732
+ // FESMs, we resolve the `@angular/core` path and verify that the path for the
733
+ // module starts with it.
734
+ // This may be slower but it will be compatible with both APF5, 6 and potential future
735
+ // versions (until the dynamic import appears outside of core I suppose).
736
+ // We resolve symbolic links in order to get the real path that would be used in webpack.
737
+ const angularCoreResourceRoot = fs . realpathSync ( path . dirname ( angularCorePackagePath ) ) ;
738
+
739
+ cmf . hooks . afterResolve . tapPromise ( 'angular-compiler' , async result => {
740
+ // Alter only existing request from Angular or the additional lazy module resources.
741
+ const isLazyModuleResource = ( resource : string ) =>
742
+ resource . startsWith ( angularCoreResourceRoot ) ||
743
+ ( this . options . additionalLazyModuleResources &&
744
+ this . options . additionalLazyModuleResources . includes ( resource ) ) ;
745
+
746
+ if ( ! result || ! this . done || ! isLazyModuleResource ( result . resource ) ) {
752
747
return result ;
753
- } ,
754
- ( ) => undefined ,
755
- ) ;
748
+ }
749
+
750
+ return this . done . then (
751
+ ( ) => {
752
+ // This folder does not exist, but we need to give webpack a resource.
753
+ // TODO: check if we can't just leave it as is (angularCoreModuleDir).
754
+ result . resource = path . join ( this . _basePath , '$$_lazy_route_resource' ) ;
755
+ // tslint:disable-next-line:no-any
756
+ result . dependencies . forEach ( ( d : any ) => d . critical = false ) ;
757
+ // tslint:disable-next-line:no-any
758
+ result . resolveDependencies = ( _fs : any , options : any , callback : Callback ) => {
759
+ const dependencies = Object . keys ( this . _lazyRoutes )
760
+ . map ( ( key ) => {
761
+ const modulePath = this . _lazyRoutes [ key ] ;
762
+ if ( modulePath !== null ) {
763
+ const name = key . split ( '#' ) [ 0 ] ;
764
+
765
+ return new this . _contextElementDependencyConstructor ( modulePath , name ) ;
766
+ } else {
767
+ return null ;
768
+ }
769
+ } )
770
+ . filter ( x => ! ! x ) ;
771
+
772
+ if ( this . _options . nameLazyFiles ) {
773
+ options . chunkName = '[request]' ;
774
+ }
775
+
776
+ callback ( null , dependencies ) ;
777
+ } ;
778
+
779
+ return result ;
780
+ } ,
781
+ ( ) => undefined ,
782
+ ) ;
783
+ } ) ;
756
784
} ) ;
757
- } ) ;
785
+ }
758
786
759
787
// Create and destroy forked type checker on watch mode.
760
788
compiler . hooks . watchRun . tap ( 'angular-compiler' , ( ) => {
@@ -922,27 +950,29 @@ export class AngularCompilerPlugin {
922
950
// Make a new program and load the Angular structure.
923
951
await this . _createOrUpdateProgram ( ) ;
924
952
925
- // Try to find lazy routes if we have an entry module.
926
- // We need to run the `listLazyRoutes` the first time because it also navigates libraries
927
- // and other things that we might miss using the (faster) findLazyRoutesInAst.
928
- // Lazy routes modules will be read with compilerHost and added to the changed files.
929
- let lazyRouteMap : LazyRouteMap = { } ;
930
- if ( ! this . _JitMode || this . _firstRun ) {
931
- lazyRouteMap = this . _listLazyRoutesFromProgram ( ) ;
932
- } else {
933
- const changedTsFiles = this . _getChangedTsFiles ( ) ;
934
- if ( changedTsFiles . length > 0 ) {
935
- lazyRouteMap = this . _findLazyRoutesInAst ( changedTsFiles ) ;
953
+ if ( this . _discoverLazyRoutes ) {
954
+ // Try to find lazy routes if we have an entry module.
955
+ // We need to run the `listLazyRoutes` the first time because it also navigates libraries
956
+ // and other things that we might miss using the (faster) findLazyRoutesInAst.
957
+ // Lazy routes modules will be read with compilerHost and added to the changed files.
958
+ let lazyRouteMap : LazyRouteMap = { } ;
959
+ if ( ! this . _JitMode || this . _firstRun ) {
960
+ lazyRouteMap = this . _listLazyRoutesFromProgram ( ) ;
961
+ } else {
962
+ const changedTsFiles = this . _getChangedTsFiles ( ) ;
963
+ if ( changedTsFiles . length > 0 ) {
964
+ lazyRouteMap = this . _findLazyRoutesInAst ( changedTsFiles ) ;
965
+ }
936
966
}
937
- }
938
967
939
- // Find lazy routes
940
- lazyRouteMap = {
941
- ...lazyRouteMap ,
942
- ...this . _options . additionalLazyModules ,
943
- } ;
968
+ // Find lazy routes
969
+ lazyRouteMap = {
970
+ ...lazyRouteMap ,
971
+ ...this . _options . additionalLazyModules ,
972
+ } ;
944
973
945
- this . _processLazyRoutes ( lazyRouteMap ) ;
974
+ this . _processLazyRoutes ( lazyRouteMap ) ;
975
+ }
946
976
947
977
// Emit files.
948
978
time ( 'AngularCompilerPlugin._update._emit' ) ;
0 commit comments