diff --git a/packages/schematics/angular/module/index.ts b/packages/schematics/angular/module/index.ts index 83f5c5f67156..7c72e37962e2 100644 --- a/packages/schematics/angular/module/index.ts +++ b/packages/schematics/angular/module/index.ts @@ -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() diff --git a/packages/schematics/angular/module/index_spec.ts b/packages/schematics/angular/module/index_spec.ts index bfa99e9ab007..8cd9f1c62c21 100644 --- a/packages/schematics/angular/module/index_spec.ts +++ b/packages/schematics/angular/module/index_spec.ts @@ -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)`); + }); }); }); diff --git a/packages/schematics/angular/utility/find-module.ts b/packages/schematics/angular/utility/find-module.ts index 329b9f445e6f..cc9225289941 100644 --- a/packages/schematics/angular/utility/find-module.ts +++ b/packages/schematics/angular/utility/find-module.ts @@ -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.