feat(angular): support library routing setup for standalone routes (#11634)
This commit is contained in:
parent
4d1acadf6e
commit
09112ccd24
@ -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",
|
||||
|
||||
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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}
|
||||
]"
|
||||
`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -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",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user