Skip to content

Commit 9d6a15a

Browse files
committed
feat(@ngtools/webpack): add option to control lazy route discovery
1 parent 1a4f364 commit 9d6a15a

File tree

1 file changed

+85
-75
lines changed

1 file changed

+85
-75
lines changed

packages/ngtools/webpack/src/angular_compiler_plugin.ts

+85-75
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.',
@@ -703,64 +709,66 @@ export class AngularCompilerPlugin {
703709
);
704710
});
705711

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

765773
// Create and destroy forked type checker on watch mode.
766774
compiler.hooks.watchRun.tap('angular-compiler', () => {
@@ -943,27 +951,29 @@ export class AngularCompilerPlugin {
943951
// Make a new program and load the Angular structure.
944952
await this._createOrUpdateProgram();
945953

946-
// Try to find lazy routes if we have an entry module.
947-
// We need to run the `listLazyRoutes` the first time because it also navigates libraries
948-
// and other things that we might miss using the (faster) findLazyRoutesInAst.
949-
// Lazy routes modules will be read with compilerHost and added to the changed files.
950-
let lazyRouteMap: LazyRouteMap = {};
951-
if (!this._JitMode || this._firstRun) {
952-
lazyRouteMap = this._listLazyRoutesFromProgram();
953-
} else {
954-
const changedTsFiles = this._getChangedTsFiles();
955-
if (changedTsFiles.length > 0) {
956-
lazyRouteMap = this._findLazyRoutesInAst(changedTsFiles);
954+
if (this._discoverLazyRoutes) {
955+
// Try to find lazy routes if we have an entry module.
956+
// We need to run the `listLazyRoutes` the first time because it also navigates libraries
957+
// and other things that we might miss using the (faster) findLazyRoutesInAst.
958+
// Lazy routes modules will be read with compilerHost and added to the changed files.
959+
let lazyRouteMap: LazyRouteMap = {};
960+
if (!this._JitMode || this._firstRun) {
961+
lazyRouteMap = this._listLazyRoutesFromProgram();
962+
} else {
963+
const changedTsFiles = this._getChangedTsFiles();
964+
if (changedTsFiles.length > 0) {
965+
lazyRouteMap = this._findLazyRoutesInAst(changedTsFiles);
966+
}
957967
}
958-
}
959968

960-
// Find lazy routes
961-
lazyRouteMap = {
962-
...lazyRouteMap,
963-
...this._options.additionalLazyModules,
964-
};
969+
// Find lazy routes
970+
lazyRouteMap = {
971+
...lazyRouteMap,
972+
...this._options.additionalLazyModules,
973+
};
965974

966-
this._processLazyRoutes(lazyRouteMap);
975+
this._processLazyRoutes(lazyRouteMap);
976+
}
967977

968978
// Emit files.
969979
time('AngularCompilerPlugin._update._emit');

0 commit comments

Comments
 (0)