Skip to content
This repository has been archived by the owner on Apr 9, 2022. It is now read-only.

Commit

Permalink
feat(@schematics/angular): support entryComponent
Browse files Browse the repository at this point in the history
  • Loading branch information
JLHwung authored and filipesilva committed May 21, 2018
1 parent f05698f commit 92cfd97
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 13 deletions.
47 changes: 34 additions & 13 deletions packages/schematics/angular/component/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,27 @@ import {
url,
} from '@angular-devkit/schematics';
import * as ts from 'typescript';
import { addDeclarationToModule, addExportToModule } from '../utility/ast-utils';
import {
addDeclarationToModule,
addEntryComponentToModule,
addExportToModule,
} from '../utility/ast-utils';
import { InsertChange } from '../utility/change';
import { getWorkspace } from '../utility/config';
import { buildRelativePath, findModuleFromOptions } from '../utility/find-module';
import { parseName } from '../utility/parse-name';
import { validateHtmlSelector, validateName } from '../utility/validation';
import { Schema as ComponentOptions } from './schema';

function readIntoSourceFile(host: Tree, modulePath: string): ts.SourceFile {
const text = host.read(modulePath);
if (text === null) {
throw new SchematicsException(`File ${modulePath} does not exist.`);
}
const sourceText = text.toString('utf-8');

return ts.createSourceFile(modulePath, sourceText, ts.ScriptTarget.Latest, true);
}

function addDeclarationToNgModule(options: ComponentOptions): Rule {
return (host: Tree) => {
Expand All @@ -38,12 +51,7 @@ function addDeclarationToNgModule(options: ComponentOptions): Rule {
}

const modulePath = options.module;
const text = host.read(modulePath);
if (text === null) {
throw new SchematicsException(`File ${modulePath} does not exist.`);
}
const sourceText = text.toString('utf-8');
const source = ts.createSourceFile(modulePath, sourceText, ts.ScriptTarget.Latest, true);
const source = readIntoSourceFile(host, modulePath);

const componentPath = `/${options.path}/`
+ (options.flat ? '' : strings.dasherize(options.name) + '/')
Expand All @@ -66,12 +74,7 @@ function addDeclarationToNgModule(options: ComponentOptions): Rule {

if (options.export) {
// Need to refresh the AST because we overwrote the file in the host.
const text = host.read(modulePath);
if (text === null) {
throw new SchematicsException(`File ${modulePath} does not exist.`);
}
const sourceText = text.toString('utf-8');
const source = ts.createSourceFile(modulePath, sourceText, ts.ScriptTarget.Latest, true);
const source = readIntoSourceFile(host, modulePath);

const exportRecorder = host.beginUpdate(modulePath);
const exportChanges = addExportToModule(source, modulePath,
Expand All @@ -86,6 +89,24 @@ function addDeclarationToNgModule(options: ComponentOptions): Rule {
host.commitUpdate(exportRecorder);
}

if (options.entryComponent) {
// Need to refresh the AST because we overwrote the file in the host.
const source = readIntoSourceFile(host, modulePath);

const entryComponentRecorder = host.beginUpdate(modulePath);
const entryComponentChanges = addEntryComponentToModule(
source, modulePath,
strings.classify(`${options.name}Component`),
relativePath);

for (const change of entryComponentChanges) {
if (change instanceof InsertChange) {
entryComponentRecorder.insertLeft(change.pos, change.toAdd);
}
}
host.commitUpdate(entryComponentRecorder);
}


return host;
};
Expand Down
8 changes: 8 additions & 0 deletions packages/schematics/angular/component/index_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,14 @@ describe('Component Schematic', () => {
expect(appModuleContent).toMatch(/exports: \[FooComponent\]/);
});

it('should set the entry component', () => {
const options = { ...defaultOptions, entryComponent: true };

const tree = schematicRunner.runSchematic('component', options, appTree);
const appModuleContent = tree.readContent('/projects/bar/src/app/app.module.ts');
expect(appModuleContent).toMatch(/entryComponents: \[FooComponent\]/);
});

it('should import into a specified module', () => {
const options = { ...defaultOptions, module: 'app.module.ts' };

Expand Down
4 changes: 4 additions & 0 deletions packages/schematics/angular/component/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,8 @@ export interface Schema {
* Specifies if declaring module exports the component.
*/
export?: boolean;
/**
* Specifies if the component is an entry component of declaring module.
*/
entryComponent?: boolean;
}
5 changes: 5 additions & 0 deletions packages/schematics/angular/component/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@
"type": "boolean",
"default": false,
"description": "Specifies if declaring module exports the component."
},
"entryComponent": {
"type": "boolean",
"default": false,
"description": "Specifies if the component is an entry component of declaring module."
}
},
"required": []
Expand Down
12 changes: 12 additions & 0 deletions packages/schematics/angular/utility/ast-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,18 @@ export function addBootstrapToModule(source: ts.SourceFile,
return addSymbolToNgModuleMetadata(source, modulePath, 'bootstrap', classifiedName, importPath);
}

/**
* Custom function to insert an entryComponent into NgModule. It also imports it.
*/
export function addEntryComponentToModule(source: ts.SourceFile,
modulePath: string, classifiedName: string,
importPath: string): Change[] {
return addSymbolToNgModuleMetadata(
source, modulePath,
'entryComponents', classifiedName, importPath,
);
}

/**
* Determine if an import already exists.
*/
Expand Down

0 comments on commit 92cfd97

Please sign in to comment.