fix(@schematics/angular): lazy loading module generation routing module lookup

Fixes: #15552
This commit is contained in:
Alan Agius 2019-09-09 20:41:01 +02:00 committed by Keen Yee Liau
parent b204dd8dce
commit fcea2443aa
3 changed files with 65 additions and 28 deletions

View File

@ -23,7 +23,7 @@ import {
import * as ts from '../third_party/github.com/Microsoft/TypeScript/lib/typescript';
import { addImportToModule, addRouteDeclarationToModule } from '../utility/ast-utils';
import { InsertChange } from '../utility/change';
import { buildRelativePath, findModuleFromOptions } from '../utility/find-module';
import { MODULE_EXT, ROUTING_MODULE_EXT, buildRelativePath, findModuleFromOptions } from '../utility/find-module';
import { applyLintFix } from '../utility/lint-fix';
import { parseName } from '../utility/parse-name';
import { createDefaultPath } from '../utility/workspace';
@ -112,17 +112,12 @@ function addRouteDeclarationToNgModule(
};
}
function getRoutingModulePath(host: Tree, options: ModuleOptions): Path | undefined {
let path: Path | undefined;
const modulePath = options.module as string;
const routingModuleName = modulePath.split('.')[0] + '-routing';
const { module, ...rest } = options;
function getRoutingModulePath(host: Tree, modulePath: string): Path | undefined {
const routingModulePath = modulePath.endsWith(ROUTING_MODULE_EXT)
? modulePath
: modulePath.replace(MODULE_EXT, ROUTING_MODULE_EXT);
try {
path = findModuleFromOptions(host, { module: routingModuleName, ...rest });
} catch {}
return path;
return host.exists(routingModulePath) ? normalize(routingModulePath) : undefined;
}
function buildRoute(options: ModuleOptions, modulePath: string) {
@ -143,17 +138,17 @@ export default function (options: ModuleOptions): Rule {
options.module = findModuleFromOptions(host, options);
}
const parsedPath = parseName(options.path, options.name);
options.name = parsedPath.name;
options.path = parsedPath.path;
let routingModulePath: Path | undefined;
const isLazyLoadedModuleGen = options.route && options.module;
if (isLazyLoadedModuleGen) {
options.routingScope = RoutingScope.Child;
routingModulePath = getRoutingModulePath(host, options);
routingModulePath = getRoutingModulePath(host, options.module as string);
}
const parsedPath = parseName(options.path, options.name);
options.name = parsedPath.name;
options.path = parsedPath.path;
const templateSource = apply(url('./files'), [
options.routing || isLazyLoadedModuleGen && !!routingModulePath
? noop()

View File

@ -10,6 +10,7 @@ import { Schema as ApplicationOptions } from '../application/schema';
import { Schema as WorkspaceOptions } from '../workspace/schema';
import { Schema as ModuleOptions } from './schema';
// tslint:disable-next-line: no-big-function
describe('Module Schematic', () => {
const schematicRunner = new SchematicTestRunner(
'@schematics/angular',
@ -129,11 +130,13 @@ describe('Module Schematic', () => {
const tree = await schematicRunner.runSchematicAsync('module', options, appTree).toPromise();
const files = tree.files;
expect(files).toContain('/projects/bar/src/app/foo/foo.module.ts');
expect(files).toContain('/projects/bar/src/app/foo/foo-routing.module.ts');
expect(files).toContain('/projects/bar/src/app/foo/foo.component.ts');
expect(files).toContain('/projects/bar/src/app/foo/foo.component.html');
expect(files).toContain('/projects/bar/src/app/foo/foo.component.css');
expect(files).toEqual(jasmine.arrayContaining([
'/projects/bar/src/app/foo/foo.module.ts',
'/projects/bar/src/app/foo/foo-routing.module.ts',
'/projects/bar/src/app/foo/foo.component.ts',
'/projects/bar/src/app/foo/foo.component.html',
'/projects/bar/src/app/foo/foo.component.css',
]));
const appRoutingModuleContent = tree.readContent('/projects/bar/src/app/app-routing.module.ts');
expect(appRoutingModuleContent).toMatch(
@ -196,16 +199,55 @@ describe('Module Schematic', () => {
).toPromise();
const files = tree.files;
expect(files).toContain('/projects/bar/src/app/foo.module.ts');
expect(files).toContain('/projects/bar/src/app/foo-routing.module.ts');
expect(files).toContain('/projects/bar/src/app/foo.component.ts');
expect(files).toContain('/projects/bar/src/app/foo.component.html');
expect(files).toContain('/projects/bar/src/app/foo.component.css');
expect(files).toEqual(jasmine.arrayContaining([
'/projects/bar/src/app/foo.module.ts',
'/projects/bar/src/app/foo-routing.module.ts',
'/projects/bar/src/app/foo.component.ts',
'/projects/bar/src/app/foo.component.html',
'/projects/bar/src/app/foo.component.css',
]));
const appRoutingModuleContent = tree.readContent('/projects/bar/src/app/app-routing.module.ts');
expect(appRoutingModuleContent).toMatch(
/path: '\/new-route', loadChildren: \(\) => import\('.\/foo.module'\).then\(m => m.FooModule\)/,
);
});
it('should generate a lazy loaded module and add route in another parallel routing module', async () => {
await schematicRunner.runSchematicAsync(
'module',
{
...defaultOptions,
name: 'foo',
routing: true,
},
appTree,
).toPromise();
const tree = await schematicRunner.runSchematicAsync(
'module',
{
...defaultOptions,
name: 'bar',
module: 'foo',
route: 'new-route',
},
appTree,
).toPromise();
expect(tree.files).toEqual(jasmine.arrayContaining([
'/projects/bar/src/app/foo/foo-routing.module.ts',
'/projects/bar/src/app/foo/foo.module.ts',
'/projects/bar/src/app/bar/bar-routing.module.ts',
'/projects/bar/src/app/bar/bar.module.ts',
'/projects/bar/src/app/bar/bar.component.ts',
]));
const barRoutingModuleContent = tree.readContent('/projects/bar/src/app/bar/bar-routing.module.ts');
expect(barRoutingModuleContent).toContain(`path: '', component: BarComponent `);
const fooRoutingModuleContent = tree.readContent('/projects/bar/src/app/foo/foo-routing.module.ts');
expect(fooRoutingModuleContent).toContain(`loadChildren: () => import('../bar/bar.module').then(m => m.BarModule)`);
});
});
});

View File

@ -26,8 +26,8 @@ export interface ModuleOptions {
routingModuleExt?: string;
}
const MODULE_EXT = '.module.ts';
const ROUTING_MODULE_EXT = '-routing.module.ts';
export const MODULE_EXT = '.module.ts';
export const ROUTING_MODULE_EXT = '-routing.module.ts';
/**
* Find the module referred by a set of options passed to the schematics.