fix(compiler-cli): add support for more than 2 levels of nested lazy routes
This change adds Compiler CLI support for any level of nesting for lazy routes. For example `{app-root}/lazy-loaded-module-1/lazy-loaded-module-2/lazy-loaded-module-3` Where `lazy-loaded-module-3` is lazy loaded from `lazy-loaded-module-2`, and `lazy-loaded-module-2` is lazy loaded from module `lazy-loaded-module-1`, and `lazy-loaded-module-1` is lazy loaded from `AppModule` Fixes angular/angular-cli#3663
This commit is contained in:
parent
d061adc02d
commit
5d9cbd7d6f
|
@ -0,0 +1,23 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright Google Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by an MIT-style license that can be
|
||||||
|
* found in the LICENSE file at https://angular.io/license
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {Component, NgModule} from '@angular/core';
|
||||||
|
import {RouterModule} from '@angular/router';
|
||||||
|
|
||||||
|
@Component({selector: 'lazy-feature-comp', template: 'lazy feature, nested!'})
|
||||||
|
export class LazyFeatureNestedComponent {
|
||||||
|
}
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [RouterModule.forChild([
|
||||||
|
{path: '', component: LazyFeatureNestedComponent, pathMatch: 'full'},
|
||||||
|
])],
|
||||||
|
declarations: [LazyFeatureNestedComponent]
|
||||||
|
})
|
||||||
|
export class LazyFeatureNestedModule {
|
||||||
|
}
|
|
@ -16,7 +16,10 @@ export class LazyFeatureComponent {
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [RouterModule.forChild([
|
imports: [RouterModule.forChild([
|
||||||
{path: '', component: LazyFeatureComponent, pathMatch: 'full'},
|
{path: '', component: LazyFeatureComponent, pathMatch: 'full'},
|
||||||
{path: 'feature', loadChildren: './feature.module#FeatureModule'}
|
{path: 'feature', loadChildren: './feature.module#FeatureModule'}, {
|
||||||
|
path: 'nested-feature',
|
||||||
|
loadChildren: './lazy-feature-nested.module#LazyFeatureNestedModule'
|
||||||
|
}
|
||||||
])],
|
])],
|
||||||
declarations: [LazyFeatureComponent]
|
declarations: [LazyFeatureComponent]
|
||||||
})
|
})
|
||||||
|
|
|
@ -191,6 +191,8 @@ function lazyRoutesTest() {
|
||||||
'./lazy.module#LazyModule': 'lazy.module.ts',
|
'./lazy.module#LazyModule': 'lazy.module.ts',
|
||||||
'./feature/feature.module#FeatureModule': 'feature/feature.module.ts',
|
'./feature/feature.module#FeatureModule': 'feature/feature.module.ts',
|
||||||
'./feature/lazy-feature.module#LazyFeatureModule': 'feature/lazy-feature.module.ts',
|
'./feature/lazy-feature.module#LazyFeatureModule': 'feature/lazy-feature.module.ts',
|
||||||
|
'./feature.module#FeatureModule': 'feature/feature.module.ts',
|
||||||
|
'./lazy-feature-nested.module#LazyFeatureNestedModule': 'feature/lazy-feature-nested.module.ts',
|
||||||
'feature2/feature2.module#Feature2Module': 'feature2/feature2.module.ts',
|
'feature2/feature2.module#Feature2Module': 'feature2/feature2.module.ts',
|
||||||
'./default.module': 'feature2/default.module.ts',
|
'./default.module': 'feature2/default.module.ts',
|
||||||
'feature/feature.module#FeatureModule': 'feature/feature.module.ts'
|
'feature/feature.module#FeatureModule': 'feature/feature.module.ts'
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
import {AotCompilerHost, StaticReflector, StaticSymbol} from '@angular/compiler';
|
import {AotCompilerHost, StaticReflector, StaticSymbol} from '@angular/compiler';
|
||||||
import {NgModule} from '@angular/core';
|
import {NgModule} from '@angular/core';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// We cannot depend directly to @angular/router.
|
// We cannot depend directly to @angular/router.
|
||||||
type Route = any;
|
type Route = any;
|
||||||
const ROUTER_MODULE_PATH = '@angular/router/src/router_config_loader';
|
const ROUTER_MODULE_PATH = '@angular/router/src/router_config_loader';
|
||||||
|
@ -63,29 +61,37 @@ export function listLazyRoutesOfModule(
|
||||||
const className = entryRouteDef.className;
|
const className = entryRouteDef.className;
|
||||||
|
|
||||||
// List loadChildren of this single module.
|
// List loadChildren of this single module.
|
||||||
const staticSymbol = reflector.findDeclaration(modulePath, className, containingFile);
|
const appStaticSymbol = reflector.findDeclaration(modulePath, className, containingFile);
|
||||||
const ROUTES = reflector.findDeclaration(ROUTER_MODULE_PATH, ROUTER_ROUTES_SYMBOL_NAME);
|
const ROUTES = reflector.findDeclaration(ROUTER_MODULE_PATH, ROUTER_ROUTES_SYMBOL_NAME);
|
||||||
const lazyRoutes: LazyRoute[] =
|
const lazyRoutes: LazyRoute[] =
|
||||||
_extractLazyRoutesFromStaticModule(staticSymbol, reflector, host, ROUTES);
|
_extractLazyRoutesFromStaticModule(appStaticSymbol, reflector, host, ROUTES);
|
||||||
const routes: LazyRouteMap = {};
|
|
||||||
|
|
||||||
lazyRoutes.forEach((lazyRoute: LazyRoute) => {
|
const allLazyRoutes = lazyRoutes.reduce(
|
||||||
const route: string = lazyRoute.routeDef.toString();
|
function includeLazyRouteAndSubRoutes(allRoutes: LazyRouteMap, lazyRoute: LazyRoute):
|
||||||
_assertRoute(routes, lazyRoute);
|
LazyRouteMap {
|
||||||
routes[route] = lazyRoute;
|
const route: string = lazyRoute.routeDef.toString();
|
||||||
|
_assertRoute(allRoutes, lazyRoute);
|
||||||
|
allRoutes[route] = lazyRoute;
|
||||||
|
|
||||||
const lazyModuleSymbol = reflector.findDeclaration(
|
// StaticReflector does not support discovering annotations like `NgModule` on default
|
||||||
lazyRoute.absoluteFilePath, lazyRoute.routeDef.className || 'default');
|
// exports
|
||||||
const subRoutes = _extractLazyRoutesFromStaticModule(lazyModuleSymbol, reflector, host, ROUTES);
|
// Which means: if a default export NgModule was lazy-loaded, we can discover it, but,
|
||||||
|
// we cannot parse its routes to see if they have loadChildren or not.
|
||||||
|
if (!lazyRoute.routeDef.className) {
|
||||||
|
return allRoutes;
|
||||||
|
}
|
||||||
|
|
||||||
// Populate the map using the routes we just found.
|
const lazyModuleSymbol = reflector.findDeclaration(
|
||||||
subRoutes.forEach(subRoute => {
|
lazyRoute.absoluteFilePath, lazyRoute.routeDef.className || 'default');
|
||||||
_assertRoute(routes, subRoute);
|
|
||||||
routes[subRoute.routeDef.toString()] = subRoute;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return routes;
|
const subRoutes =
|
||||||
|
_extractLazyRoutesFromStaticModule(lazyModuleSymbol, reflector, host, ROUTES);
|
||||||
|
|
||||||
|
return subRoutes.reduce(includeLazyRouteAndSubRoutes, allRoutes);
|
||||||
|
},
|
||||||
|
{});
|
||||||
|
|
||||||
|
return allLazyRoutes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue