Skip to content

Commit eed4b0d

Browse files
committed
feat(@ngtools/webpack): add option to control lazy route discovery
1 parent 4782b1b commit eed4b0d

File tree

1 file changed

+85
-75
lines changed

1 file changed

+85
-75
lines changed

packages/ngtools/webpack/src/angular_compiler_plugin.ts

Lines changed: 85 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ export interface AngularCompilerPluginOptions {
103103
nameLazyFiles?: boolean;
104104
logger?: logging.Logger;
105105
directTemplateLoading?: boolean;
106+
discoverLazyRoutes?: boolean;
106107

107108
// added to the list of lazy routes
108109
additionalLazyModules?: { [module: string]: string };
@@ -134,6 +135,7 @@ export class AngularCompilerPlugin {
134135
private _compilerHost: WebpackCompilerHost & CompilerHost;
135136
private _moduleResolutionCache: ts.ModuleResolutionCache;
136137
private _resourceLoader?: WebpackResourceLoader;
138+
private _discoverLazyRoutes = true;
137139
// Contains `moduleImportPath#exportName` => `fullModulePath`.
138140
private _lazyRoutes: LazyRouteMap = {};
139141
private _tsConfigPath: string;
@@ -292,6 +294,10 @@ export class AngularCompilerPlugin {
292294
this._platformTransformers = options.platformTransformers;
293295
}
294296

297+
if (options.discoverLazyRoutes !== undefined) {
298+
this._discoverLazyRoutes = options.discoverLazyRoutes;
299+
}
300+
295301
// Default ContextElementDependency to the one we can import from here.
296302
// Failing to use the right ContextElementDependency will throw the error below:
297303
// "No module factory available for dependency type: ContextElementDependency"
@@ -411,7 +417,7 @@ export class AngularCompilerPlugin {
411417
this._entryModule = resolveEntryModuleFromMain(
412418
this._mainPath, this._compilerHost, this._getTsProgram() as ts.Program);
413419

414-
if (!this.entryModule && !this._compilerOptions.enableIvy) {
420+
if (this._discoverLazyRoutes && !this.entryModule && !this._compilerOptions.enableIvy) {
415421
this._warnings.push('Lazy routes discovery is not enabled. '
416422
+ 'Because there is neither an entryModule nor a '
417423
+ 'statically analyzable bootstrap code in the main file.',
@@ -697,64 +703,66 @@ export class AngularCompilerPlugin {
697703
);
698704
});
699705

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-
706+
if (this._discoverLazyRoutes) {
707+
// Add lazy modules to the context module for @angular/core
708+
compiler.hooks.contextModuleFactory.tap('angular-compiler', cmf => {
709+
const angularCorePackagePath = require.resolve('@angular/core/package.json');
710+
711+
// APFv6 does not have single FESM anymore. Instead of verifying if we're pointing to
712+
// FESMs, we resolve the `@angular/core` path and verify that the path for the
713+
// module starts with it.
714+
// This may be slower but it will be compatible with both APF5, 6 and potential future
715+
// versions (until the dynamic import appears outside of core I suppose).
716+
// We resolve symbolic links in order to get the real path that would be used in webpack.
717+
const angularCoreResourceRoot = fs.realpathSync(path.dirname(angularCorePackagePath));
718+
719+
cmf.hooks.afterResolve.tapPromise('angular-compiler', async result => {
720+
// Alter only existing request from Angular or the additional lazy module resources.
721+
const isLazyModuleResource = (resource: string) =>
722+
resource.startsWith(angularCoreResourceRoot) ||
723+
( this.options.additionalLazyModuleResources &&
724+
this.options.additionalLazyModuleResources.includes(resource));
725+
726+
if (!result || !this.done || !isLazyModuleResource(result.resource)) {
752727
return result;
753-
},
754-
() => undefined,
755-
);
728+
}
729+
730+
return this.done.then(
731+
() => {
732+
// This folder does not exist, but we need to give webpack a resource.
733+
// TODO: check if we can't just leave it as is (angularCoreModuleDir).
734+
result.resource = path.join(this._basePath, '$$_lazy_route_resource');
735+
// tslint:disable-next-line:no-any
736+
result.dependencies.forEach((d: any) => d.critical = false);
737+
// tslint:disable-next-line:no-any
738+
result.resolveDependencies = (_fs: any, options: any, callback: Callback) => {
739+
const dependencies = Object.keys(this._lazyRoutes)
740+
.map((key) => {
741+
const modulePath = this._lazyRoutes[key];
742+
if (modulePath !== null) {
743+
const name = key.split('#')[0];
744+
745+
return new this._contextElementDependencyConstructor(modulePath, name);
746+
} else {
747+
return null;
748+
}
749+
})
750+
.filter(x => !!x);
751+
752+
if (this._options.nameLazyFiles) {
753+
options.chunkName = '[request]';
754+
}
755+
756+
callback(null, dependencies);
757+
};
758+
759+
return result;
760+
},
761+
() => undefined,
762+
);
763+
});
756764
});
757-
});
765+
}
758766

759767
// Create and destroy forked type checker on watch mode.
760768
compiler.hooks.watchRun.tap('angular-compiler', () => {
@@ -922,27 +930,29 @@ export class AngularCompilerPlugin {
922930
// Make a new program and load the Angular structure.
923931
await this._createOrUpdateProgram();
924932

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);
933+
if (this._discoverLazyRoutes) {
934+
// Try to find lazy routes if we have an entry module.
935+
// We need to run the `listLazyRoutes` the first time because it also navigates libraries
936+
// and other things that we might miss using the (faster) findLazyRoutesInAst.
937+
// Lazy routes modules will be read with compilerHost and added to the changed files.
938+
let lazyRouteMap: LazyRouteMap = {};
939+
if (!this._JitMode || this._firstRun) {
940+
lazyRouteMap = this._listLazyRoutesFromProgram();
941+
} else {
942+
const changedTsFiles = this._getChangedTsFiles();
943+
if (changedTsFiles.length > 0) {
944+
lazyRouteMap = this._findLazyRoutesInAst(changedTsFiles);
945+
}
936946
}
937-
}
938947

939-
// Find lazy routes
940-
lazyRouteMap = {
941-
...lazyRouteMap,
942-
...this._options.additionalLazyModules,
943-
};
948+
// Find lazy routes
949+
lazyRouteMap = {
950+
...lazyRouteMap,
951+
...this._options.additionalLazyModules,
952+
};
944953

945-
this._processLazyRoutes(lazyRouteMap);
954+
this._processLazyRoutes(lazyRouteMap);
955+
}
946956

947957
// Emit files.
948958
time('AngularCompilerPlugin._update._emit');

0 commit comments

Comments
 (0)