feat(angular): support library routing setup for standalone routes (#11634)

This commit is contained in:
Colum Ferry 2022-08-18 15:17:04 +01:00 committed by GitHub
parent 4d1acadf6e
commit 09112ccd24
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 174 additions and 28 deletions

View File

@ -839,7 +839,8 @@
},
"parentModule": {
"type": "string",
"description": "Update the router configuration of the parent module using `loadChildren` or `children`, depending on what `lazy` is set to."
"description": "Update the router configuration of the parent module using `loadChildren` or `children`, depending on what `lazy` is set to.",
"alias": "parent"
},
"tags": {
"type": "string",

View File

@ -6,13 +6,14 @@ import {
addRoute,
} from '../../../utils/nx-devkit/ast-utils';
import { NormalizedSchema } from './normalized-schema';
import { addStandaloneRoute } from '../../../utils/nx-devkit/standalone-utils';
export function addChildren(host: Tree, options: NormalizedSchema) {
if (!host.exists(options.parentModule)) {
export function addChildren(tree: Tree, options: NormalizedSchema) {
if (!tree.exists(options.parentModule)) {
throw new Error(`Cannot find '${options.parentModule}'`);
}
const moduleSource = host.read(options.parentModule, 'utf-8');
const moduleSource = tree.read(options.parentModule, 'utf-8');
const constName = options.standalone
? `${names(options.name).className.toUpperCase()}_ROUTES`
: `${names(options.fileName).propertyName}Routes`;
@ -26,24 +27,35 @@ export function addChildren(host: Tree, options: NormalizedSchema) {
if (!options.standalone) {
sourceFile = addImportToModule(
host,
tree,
sourceFile,
options.parentModule,
options.moduleName
);
}
sourceFile = addRoute(
host,
options.parentModule,
sourceFile,
`{ path: '${names(options.fileName).fileName}', children: ${constName} }`
);
sourceFile = insertImport(
host,
tree,
sourceFile,
options.parentModule,
options.standalone ? constName : `${options.moduleName}, ${constName}`,
importPath
);
const route = `{ path: '${
names(options.fileName).fileName
}', children: ${constName} }`;
if (moduleSource.includes('@NgModule')) {
sourceFile = addRoute(tree, options.parentModule, sourceFile, route);
} else {
addStandaloneRoute(
tree,
options.parentModule,
route,
false,
constName,
importPath
);
}
}

View File

@ -2,13 +2,14 @@ import { names, Tree } from '@nrwl/devkit';
import * as ts from 'typescript';
import { addRoute } from '../../../utils/nx-devkit/ast-utils';
import { NormalizedSchema } from './normalized-schema';
import { addStandaloneRoute } from '../../../utils/nx-devkit/standalone-utils';
export function addLoadChildren(host: Tree, options: NormalizedSchema) {
if (!host.exists(options.parentModule)) {
export function addLoadChildren(tree: Tree, options: NormalizedSchema) {
if (!tree.exists(options.parentModule)) {
throw new Error(`Cannot find '${options.parentModule}'`);
}
const moduleSource = host.read(options.parentModule)!.toString('utf-8');
const moduleSource = tree.read(options.parentModule)!.toString('utf-8');
const sourceFile = ts.createSourceFile(
options.parentModule,
moduleSource,
@ -16,16 +17,17 @@ export function addLoadChildren(host: Tree, options: NormalizedSchema) {
true
);
addRoute(
host,
options.parentModule,
sourceFile,
`{path: '${
names(options.fileName).fileName
}', loadChildren: () => import('${options.importPath}').then(m => m.${
options.standalone
? `${names(options.name).className.toUpperCase()}_ROUTES`
: options.moduleName
})}`
);
const route = `{path: '${
names(options.fileName).fileName
}', loadChildren: () => import('${options.importPath}').then(m => m.${
options.standalone
? `${names(options.name).className.toUpperCase()}_ROUTES`
: options.moduleName
})}`;
if (moduleSource.includes('@NgModule')) {
addRoute(tree, options.parentModule, sourceFile, route);
} else {
addStandaloneRoute(tree, options.parentModule, route);
}
}

View File

@ -1545,5 +1545,135 @@ describe('lib', () => {
tree.read('apps/app1/src/app/app.module.ts', 'utf-8')
).toMatchSnapshot();
});
it('should generate a library with a standalone component as entry point with routing setup and attach it to standalone parent module as direct child', async () => {
// ARRANGE
await applicationGenerator(tree, {
name: 'app1',
routing: true,
standalone: true,
});
// ACT
await runLibraryGeneratorWithOpts({
standalone: true,
routing: true,
parentModule: 'apps/app1/src/main.ts',
});
// ASSERT
expect(tree.read('apps/app1/src/main.ts', 'utf-8'))
.toMatchInlineSnapshot(`
"import { enableProdMode, importProvidersFrom } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';
import { AppComponent } from './app/app.component';
import { environment } from './environments/environment';
import { MYLIB_ROUTES } from '@proj/my-lib';
if (environment.production) {
enableProdMode();
}
bootstrapApplication(AppComponent, {
providers: [importProvidersFrom(RouterModule.forRoot([
{ path: 'my-lib', children: MYLIB_ROUTES },], {initialNavigation: 'enabledBlocking'}))],
}).catch((err) => console.error(err))"
`);
});
it('should generate a library with a standalone component as entry point with routing setup and attach it to standalone parent module as a lazy child', async () => {
// ARRANGE
await applicationGenerator(tree, {
name: 'app1',
routing: true,
standalone: true,
});
// ACT
await runLibraryGeneratorWithOpts({
standalone: true,
routing: true,
lazy: true,
parentModule: 'apps/app1/src/main.ts',
});
// ASSERT
expect(tree.read('apps/app1/src/main.ts', 'utf-8'))
.toMatchInlineSnapshot(`
"import { enableProdMode, importProvidersFrom } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';
import { AppComponent } from './app/app.component';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
bootstrapApplication(AppComponent, {
providers: [importProvidersFrom(RouterModule.forRoot([
{path: 'my-lib', loadChildren: () => import('@proj/my-lib').then(m => m.MYLIB_ROUTES)},], {initialNavigation: 'enabledBlocking'}))],
}).catch((err) => console.error(err))"
`);
});
it('should generate a library with a standalone component as entry point with routing setup and attach it to standalone parent routes as direct child', async () => {
// ARRANGE
await runLibraryGeneratorWithOpts({
standalone: true,
routing: true,
});
// ACT
await runLibraryGeneratorWithOpts({
name: 'second',
standalone: true,
routing: true,
parentModule: 'libs/my-lib/src/lib/routes.ts',
});
// ASSERT
expect(tree.read('libs/my-lib/src/lib/routes.ts', 'utf-8'))
.toMatchInlineSnapshot(`
"import { Route } from '@angular/router';
import { MyLibComponent } from './my-lib/my-lib.component';
import { SECOND_ROUTES } from '@proj/second';
export const MYLIB_ROUTES: Route[] = [
{ path: 'second', children: SECOND_ROUTES },
{path: '', component: MyLibComponent}
]"
`);
});
it('should generate a library with a standalone component as entry point with routing setup and attach it to standalone parent routes as a lazy child', async () => {
// ARRANGE
await runLibraryGeneratorWithOpts({
standalone: true,
routing: true,
});
// ACT
await runLibraryGeneratorWithOpts({
name: 'second',
standalone: true,
routing: true,
lazy: true,
parentModule: 'libs/my-lib/src/lib/routes.ts',
});
// ASSERT
expect(tree.read('libs/my-lib/src/lib/routes.ts', 'utf-8'))
.toMatchInlineSnapshot(`
"import { Route } from '@angular/router';
import { MyLibComponent } from './my-lib/my-lib.component';
export const MYLIB_ROUTES: Route[] = [
{path: 'second', loadChildren: () => import('@proj/second').then(m => m.SECOND_ROUTES)},
{path: '', component: MyLibComponent}
]"
`);
});
});
});

View File

@ -78,7 +78,8 @@
},
"parentModule": {
"type": "string",
"description": "Update the router configuration of the parent module using `loadChildren` or `children`, depending on what `lazy` is set to."
"description": "Update the router configuration of the parent module using `loadChildren` or `children`, depending on what `lazy` is set to.",
"alias": "parent"
},
"tags": {
"type": "string",