fix(schematics): support app gen with inline-template
This adds the support to generate an application with the `inline-template` flag activated. Two new utils added: `getDecoratorPropertyValueNode` & `replaceNodeValue`. Add some tests ensure to test the two ways of generating template, using `templateUrls` and `inlineTemplate`. Tests are unising the flag `inlineTemplate`. close #519
This commit is contained in:
parent
ba5777735f
commit
b1b0207496
@ -240,4 +240,31 @@ describe('app', () => {
|
||||
).toContain('imports: [RouterTestingModule]');
|
||||
});
|
||||
});
|
||||
|
||||
describe('template generation mode', () => {
|
||||
it('should create Nx specific `app.component.html` template', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'app',
|
||||
{ name: 'myApp', directory: 'myDir' },
|
||||
appTree
|
||||
);
|
||||
expect(
|
||||
getFileContent(tree, 'apps/my-dir/my-app/src/app/app.component.html')
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
getFileContent(tree, 'apps/my-dir/my-app/src/app/app.component.html')
|
||||
).toContain('This is an Angular CLI app built with Nrwl Nx!');
|
||||
});
|
||||
|
||||
it("should update `template`'s property of AppComponent with Nx content", () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'app',
|
||||
{ name: 'myApp', directory: 'myDir', inlineTemplate: true },
|
||||
appTree
|
||||
);
|
||||
expect(
|
||||
getFileContent(tree, 'apps/my-dir/my-app/src/app/app.component.ts')
|
||||
).toContain('This is an Angular CLI app built with Nrwl Nx!');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -13,7 +13,9 @@ import { insertImport } from '@schematics/angular/utility/ast-utils';
|
||||
import {
|
||||
addImportToModule,
|
||||
addImportToTestBed,
|
||||
getDecoratorPropertyValueNode,
|
||||
insert,
|
||||
replaceNodeValue,
|
||||
updateJsonInTree
|
||||
} from '../../utils/ast-utils';
|
||||
import { toFileName } from '../../utils/name-utils';
|
||||
@ -117,9 +119,27 @@ Nx is designed to help you create and build enterprise grade Angular application
|
||||
const content = options.routing
|
||||
? `${baseContent}\n<router-outlet></router-outlet>`
|
||||
: baseContent;
|
||||
host.overwrite(
|
||||
`${options.appProjectRoot}/src/app/app.component.html`,
|
||||
content
|
||||
|
||||
if (!options.inlineTemplate) {
|
||||
return host.overwrite(
|
||||
`${options.appProjectRoot}/src/app/app.component.html`,
|
||||
content
|
||||
);
|
||||
}
|
||||
|
||||
const modulePath = `${options.appProjectRoot}/src/app/app.component.ts`;
|
||||
const templateNodeValue = getDecoratorPropertyValueNode(
|
||||
host,
|
||||
modulePath,
|
||||
'Component',
|
||||
'template',
|
||||
'@angular/core'
|
||||
);
|
||||
replaceNodeValue(
|
||||
host,
|
||||
modulePath,
|
||||
templateNodeValue,
|
||||
`\`\n${baseContent}\n\`,\n`
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@ -238,7 +238,12 @@ export function removeFromNgModule(
|
||||
}
|
||||
|
||||
// Get all the children property assignment of object literals.
|
||||
const matchingProperty = getMatchingProperty(source, property);
|
||||
const matchingProperty = getMatchingProperty(
|
||||
source,
|
||||
property,
|
||||
'NgModule',
|
||||
'@angular/core'
|
||||
);
|
||||
if (matchingProperty) {
|
||||
return [
|
||||
new RemoveChange(
|
||||
@ -343,7 +348,12 @@ export function getBootstrapComponent(
|
||||
source: ts.SourceFile,
|
||||
moduleClassName: string
|
||||
): string {
|
||||
const bootstrap = getMatchingProperty(source, 'bootstrap');
|
||||
const bootstrap = getMatchingProperty(
|
||||
source,
|
||||
'bootstrap',
|
||||
'NgModule',
|
||||
'@angular/core'
|
||||
);
|
||||
if (!bootstrap) {
|
||||
throw new Error(`Cannot find bootstrap components in '${moduleClassName}'`);
|
||||
}
|
||||
@ -383,9 +393,11 @@ function getMatchingObjectLiteralElement(
|
||||
|
||||
function getMatchingProperty(
|
||||
source: ts.SourceFile,
|
||||
property: string
|
||||
property: string,
|
||||
identifier: string,
|
||||
module: string
|
||||
): ts.ObjectLiteralElement {
|
||||
const nodes = getDecoratorMetadata(source, 'NgModule', '@angular/core');
|
||||
const nodes = getDecoratorMetadata(source, identifier, module);
|
||||
let node: any = nodes[0]; // tslint:disable-line:no-any
|
||||
|
||||
if (!node) return null;
|
||||
@ -424,7 +436,12 @@ export function addIncludeToTsConfig(
|
||||
}
|
||||
|
||||
function getListOfRoutes(source: ts.SourceFile): ts.NodeArray<ts.Expression> {
|
||||
const imports: any = getMatchingProperty(source, 'imports');
|
||||
const imports: any = getMatchingProperty(
|
||||
source,
|
||||
'imports',
|
||||
'NgModule',
|
||||
'@angular/core'
|
||||
);
|
||||
|
||||
if (imports.initializer.kind === ts.SyntaxKind.ArrayLiteralExpression) {
|
||||
const a = imports.initializer as ts.ArrayLiteralExpression;
|
||||
@ -888,3 +905,38 @@ export function insertImport(
|
||||
ts.SyntaxKind.StringLiteral
|
||||
);
|
||||
}
|
||||
|
||||
export function getDecoratorPropertyValueNode(
|
||||
host: Tree,
|
||||
modulePath: string,
|
||||
identifier: string,
|
||||
property: string,
|
||||
module: string
|
||||
) {
|
||||
const moduleSourceText = host.read(modulePath)!.toString('utf-8');
|
||||
const moduleSource = ts.createSourceFile(
|
||||
modulePath,
|
||||
moduleSourceText,
|
||||
ts.ScriptTarget.Latest,
|
||||
true
|
||||
);
|
||||
const templateNode = getMatchingProperty(
|
||||
moduleSource,
|
||||
property,
|
||||
identifier,
|
||||
module
|
||||
);
|
||||
|
||||
return templateNode.getChildAt(templateNode.getChildCount() - 1);
|
||||
}
|
||||
|
||||
export function replaceNodeValue(
|
||||
host: Tree,
|
||||
modulePath: string,
|
||||
node: ts.Node,
|
||||
content: string
|
||||
) {
|
||||
insert(host, modulePath, [
|
||||
new ReplaceChange(modulePath, node.pos, node.getFullText(), content)
|
||||
]);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user