Skip to content

Commit adc79f0

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

File tree

5 files changed

+49
-1
lines changed

5 files changed

+49
-1
lines changed

packages/schematics/angular/component/index.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
url,
2323
} from '@angular-devkit/schematics';
2424
import * as ts from 'typescript';
25-
import { addDeclarationToModule, addExportToModule } from '../utility/ast-utils';
25+
import { addDeclarationToModule, addExportToModule, addEntryComponentToModule } from '../utility/ast-utils';
2626
import { InsertChange } from '../utility/change';
2727
import { getWorkspace } from '../utility/config';
2828
import { buildRelativePath, findModuleFromOptions } from '../utility/find-module';
@@ -86,6 +86,28 @@ function addDeclarationToNgModule(options: ComponentOptions): Rule {
8686
host.commitUpdate(exportRecorder);
8787
}
8888

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

90112
return host;
91113
};

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: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,15 @@ 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(source, modulePath, 'entryComponents', classifiedName, importPath);
541+
}
542+
534543
/**
535544
* Determine if an import already exists.
536545
*/

0 commit comments

Comments
 (0)