feat(angular): support library routing setup for standalone routes (#11634)
This commit is contained in:
parent
4d1acadf6e
commit
09112ccd24
@ -839,7 +839,8 @@
|
|||||||
},
|
},
|
||||||
"parentModule": {
|
"parentModule": {
|
||||||
"type": "string",
|
"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": {
|
"tags": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
|||||||
@ -6,13 +6,14 @@ import {
|
|||||||
addRoute,
|
addRoute,
|
||||||
} from '../../../utils/nx-devkit/ast-utils';
|
} from '../../../utils/nx-devkit/ast-utils';
|
||||||
import { NormalizedSchema } from './normalized-schema';
|
import { NormalizedSchema } from './normalized-schema';
|
||||||
|
import { addStandaloneRoute } from '../../../utils/nx-devkit/standalone-utils';
|
||||||
|
|
||||||
export function addChildren(host: Tree, options: NormalizedSchema) {
|
export function addChildren(tree: Tree, options: NormalizedSchema) {
|
||||||
if (!host.exists(options.parentModule)) {
|
if (!tree.exists(options.parentModule)) {
|
||||||
throw new Error(`Cannot find '${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
|
const constName = options.standalone
|
||||||
? `${names(options.name).className.toUpperCase()}_ROUTES`
|
? `${names(options.name).className.toUpperCase()}_ROUTES`
|
||||||
: `${names(options.fileName).propertyName}Routes`;
|
: `${names(options.fileName).propertyName}Routes`;
|
||||||
@ -26,24 +27,35 @@ export function addChildren(host: Tree, options: NormalizedSchema) {
|
|||||||
|
|
||||||
if (!options.standalone) {
|
if (!options.standalone) {
|
||||||
sourceFile = addImportToModule(
|
sourceFile = addImportToModule(
|
||||||
host,
|
tree,
|
||||||
sourceFile,
|
sourceFile,
|
||||||
options.parentModule,
|
options.parentModule,
|
||||||
options.moduleName
|
options.moduleName
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceFile = addRoute(
|
|
||||||
host,
|
|
||||||
options.parentModule,
|
|
||||||
sourceFile,
|
|
||||||
`{ path: '${names(options.fileName).fileName}', children: ${constName} }`
|
|
||||||
);
|
|
||||||
sourceFile = insertImport(
|
sourceFile = insertImport(
|
||||||
host,
|
tree,
|
||||||
sourceFile,
|
sourceFile,
|
||||||
options.parentModule,
|
options.parentModule,
|
||||||
options.standalone ? constName : `${options.moduleName}, ${constName}`,
|
options.standalone ? constName : `${options.moduleName}, ${constName}`,
|
||||||
importPath
|
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 * as ts from 'typescript';
|
||||||
import { addRoute } from '../../../utils/nx-devkit/ast-utils';
|
import { addRoute } from '../../../utils/nx-devkit/ast-utils';
|
||||||
import { NormalizedSchema } from './normalized-schema';
|
import { NormalizedSchema } from './normalized-schema';
|
||||||
|
import { addStandaloneRoute } from '../../../utils/nx-devkit/standalone-utils';
|
||||||
|
|
||||||
export function addLoadChildren(host: Tree, options: NormalizedSchema) {
|
export function addLoadChildren(tree: Tree, options: NormalizedSchema) {
|
||||||
if (!host.exists(options.parentModule)) {
|
if (!tree.exists(options.parentModule)) {
|
||||||
throw new Error(`Cannot find '${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(
|
const sourceFile = ts.createSourceFile(
|
||||||
options.parentModule,
|
options.parentModule,
|
||||||
moduleSource,
|
moduleSource,
|
||||||
@ -16,16 +17,17 @@ export function addLoadChildren(host: Tree, options: NormalizedSchema) {
|
|||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
addRoute(
|
const route = `{path: '${
|
||||||
host,
|
names(options.fileName).fileName
|
||||||
options.parentModule,
|
}', loadChildren: () => import('${options.importPath}').then(m => m.${
|
||||||
sourceFile,
|
options.standalone
|
||||||
`{path: '${
|
? `${names(options.name).className.toUpperCase()}_ROUTES`
|
||||||
names(options.fileName).fileName
|
: options.moduleName
|
||||||
}', loadChildren: () => import('${options.importPath}').then(m => m.${
|
})}`;
|
||||||
options.standalone
|
|
||||||
? `${names(options.name).className.toUpperCase()}_ROUTES`
|
if (moduleSource.includes('@NgModule')) {
|
||||||
: options.moduleName
|
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')
|
tree.read('apps/app1/src/app/app.module.ts', 'utf-8')
|
||||||
).toMatchSnapshot();
|
).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": {
|
"parentModule": {
|
||||||
"type": "string",
|
"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": {
|
"tags": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user