Skip to content

Commit e36af00

Browse files
committed
feat(@schematics/angular): support entryComponent
Fixes angular/angular-cli#7749
1 parent cffb225 commit e36af00

File tree

5 files changed

+56
-1
lines changed

5 files changed

+56
-1
lines changed

packages/schematics/angular/component/index.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@ import {
2222
url,
2323
} from '@angular-devkit/schematics';
2424
import * as ts from 'typescript';
25-
import { addDeclarationToModule, addExportToModule } from '../utility/ast-utils';
25+
import {
26+
addDeclarationToModule,
27+
addEntryComponentToModule,
28+
addExportToModule,
29+
} from '../utility/ast-utils';
2630
import { InsertChange } from '../utility/change';
2731
import { getWorkspace } from '../utility/config';
2832
import { buildRelativePath, findModuleFromOptions } from '../utility/find-module';
@@ -86,6 +90,28 @@ function addDeclarationToNgModule(options: ComponentOptions): Rule {
8690
host.commitUpdate(exportRecorder);
8791
}
8892

93+
if (options.entryComponent) {
94+
// Need to refresh the AST because we overwrote the file in the host.
95+
const text = host.read(modulePath);
96+
if (text === null) {
97+
throw new SchematicsException(`File ${modulePath} does not exist.`);
98+
}
99+
const sourceText = text.toString('utf-8');
100+
const source = ts.createSourceFile(modulePath, sourceText, ts.ScriptTarget.Latest, true);
101+
102+
const entryComponentRecorder = host.beginUpdate(modulePath);
103+
const entryComponentChanges = addEntryComponentToModule(source, modulePath,
104+
strings.classify(`${options.name}Component`),
105+
relativePath);
106+
107+
for (const change of entryComponentChanges) {
108+
if (change instanceof InsertChange) {
109+
entryComponentRecorder.insertLeft(change.pos, change.toAdd);
110+
}
111+
}
112+
host.commitUpdate(entryComponentRecorder);
113+
}
114+
89115

90116
return host;
91117
};

packages/schematics/angular/component/index_spec.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,14 @@ describe('Component Schematic', () => {
135135
expect(appModuleContent).toMatch(/exports: \[FooComponent\]/);
136136
});
137137

138+
it('should set the entry component', () => {
139+
const options = { ...defaultOptions, entryComponent: true };
140+
141+
const tree = schematicRunner.runSchematic('component', options, appTree);
142+
const appModuleContent = tree.readContent('/projects/bar/src/app/app.module.ts');
143+
expect(appModuleContent).toMatch(/entryComponents: \[FooComponent\]/);
144+
});
145+
138146
it('should import into a specified module', () => {
139147
const options = { ...defaultOptions, module: 'app.module.ts' };
140148

packages/schematics/angular/component/schema.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,8 @@ export interface Schema {
6767
* Specifies if declaring module exports the component.
6868
*/
6969
export?: boolean;
70+
/**
71+
* Specifies if the component is an entry component of declaring module.
72+
*/
73+
entryComponent?: boolean;
7074
}

packages/schematics/angular/component/schema.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@
9898
"type": "boolean",
9999
"default": false,
100100
"description": "Specifies if declaring module exports the component."
101+
},
102+
"entryComponent": {
103+
"type": "boolean",
104+
"default": false,
105+
"description": "Specifies if the component is an entry component of declaring module."
101106
}
102107
},
103108
"required": []

packages/schematics/angular/utility/ast-utils.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,18 @@ export function addBootstrapToModule(source: ts.SourceFile,
531531
return addSymbolToNgModuleMetadata(source, modulePath, 'bootstrap', classifiedName, importPath);
532532
}
533533

534+
/**
535+
* Custom function to insert an entryComponent into NgModule. It also imports it.
536+
*/
537+
export function addEntryComponentToModule(source: ts.SourceFile,
538+
modulePath: string, classifiedName: string,
539+
importPath: string): Change[] {
540+
return addSymbolToNgModuleMetadata(
541+
source, modulePath,
542+
'entryComponents', classifiedName, importPath,
543+
);
544+
}
545+
534546
/**
535547
* Determine if an import already exists.
536548
*/

0 commit comments

Comments
 (0)