fix(angular): schematic to register routes

Fixes the schematic to register the route properly even if it is not directly defined at the
RouterModule registration
This commit is contained in:
Juri 2020-03-06 11:35:43 +01:00 committed by Victor Savkin
parent dae258928c
commit e5b9d80543
2 changed files with 115 additions and 2 deletions

View File

@ -4,6 +4,10 @@ import { createApp, runSchematic } from '../../utils/testing';
import * as stripJsonComments from 'strip-json-comments';
import { NxJson, readJsonInTree } from '@nrwl/workspace';
import { UnitTestTree } from '@angular-devkit/schematics/testing';
import {
stripIndents,
stripIndent
} from '@angular-devkit/core/src/utils/literals';
describe('lib', () => {
let appTree: Tree;
@ -672,6 +676,55 @@ describe('lib', () => {
'../../libs/my-dir/my-lib3/src/index.ts'
]);
});
it('should update the parent module even if the route is declared outside the .forRoot(...)', async () => {
appTree = createApp(appTree, 'myapp');
appTree.overwrite(
'apps/myapp/src/app/app.module.ts',
`
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
const routes = [];
@NgModule({
imports: [BrowserModule, RouterModule.forRoot(routes)],
declarations: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule {}
`
);
const tree = await runSchematic(
'lib',
{
name: 'myLib',
directory: 'myDir',
routing: true,
lazy: true,
framework: 'angular',
parentModule: 'apps/myapp/src/app/app.module.ts'
},
appTree
);
const moduleContents = getFileContent(
tree,
'apps/myapp/src/app/app.module.ts'
);
expect(moduleContents).toContain('RouterModule.forRoot(routes)');
expect(moduleContents).toContain(stripIndent`
const routes = [
{
path: 'my-dir-my-lib',
loadChildren: () =>
import('@proj/my-dir/my-lib').then(module => module.MyDirMyLibModule)
}
];`);
});
});
describe('eager', () => {
@ -799,6 +852,49 @@ describe('lib', () => {
"{ path: 'my-lib3', children: myLib3Routes }"
);
});
it('should update the parent module even if the route is declared outside the .forRoot(...)', async () => {
appTree = createApp(appTree, 'myapp');
appTree.overwrite(
'apps/myapp/src/app/app.module.ts',
`
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
const routes = [];
@NgModule({
imports: [BrowserModule, RouterModule.forRoot(routes)],
declarations: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule {}
`
);
const tree = await runSchematic(
'lib',
{
name: 'myLib',
directory: 'myDir',
routing: true,
framework: 'angular',
parentModule: 'apps/myapp/src/app/app.module.ts'
},
appTree
);
const moduleContents = getFileContent(
tree,
'apps/myapp/src/app/app.module.ts'
);
expect(moduleContents).toContain('RouterModule.forRoot(routes)');
expect(moduleContents).toContain(
`const routes = [{ path: 'my-dir-my-lib', children: myDirMyLibRoutes }];`
);
});
});
});

View File

@ -407,7 +407,9 @@ export function addRoute(
}
}
function getListOfRoutes(source: ts.SourceFile): ts.NodeArray<ts.Expression> {
function getListOfRoutes(
source: ts.SourceFile
): ts.NodeArray<ts.Expression> | null {
const imports: any = getMatchingProperty(
source,
'imports',
@ -418,7 +420,7 @@ function getListOfRoutes(source: ts.SourceFile): ts.NodeArray<ts.Expression> {
if (imports.initializer.kind === ts.SyntaxKind.ArrayLiteralExpression) {
const a = imports.initializer as ts.ArrayLiteralExpression;
for (let e of a.elements) {
for (const e of a.elements) {
if (e.kind === ts.SyntaxKind.CallExpression) {
const ee = e as ts.CallExpression;
const text = ee.expression.getText(source);
@ -430,6 +432,21 @@ function getListOfRoutes(source: ts.SourceFile): ts.NodeArray<ts.Expression> {
const routes = ee.arguments[0];
if (routes.kind === ts.SyntaxKind.ArrayLiteralExpression) {
return (routes as ts.ArrayLiteralExpression).elements;
} else if (routes.kind === ts.SyntaxKind.Identifier) {
// find the array expression
const variableDeclarations = findNodes(
source,
ts.SyntaxKind.VariableDeclaration
) as ts.VariableDeclaration[];
const routesDeclaration = variableDeclarations.find(x => {
return x.name.getText() === routes.getText();
});
if (routesDeclaration) {
return (routesDeclaration.initializer as ts.ArrayLiteralExpression)
.elements;
}
}
}
}