Skip to content

Commit 4f3f2e7

Browse files
committed
feat(@schematics/angular): add --standalone to ng generate
Adds the `--standalone` flag when generating components, directives or pipes through `ng generate`.
1 parent ef23b39 commit 4f3f2e7

File tree

12 files changed

+75
-6
lines changed

12 files changed

+75
-6
lines changed

packages/schematics/angular/component/files/__name@dasherize@if-flat__/__name@dasherize__.__type@dasherize__.ts.template

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { Component, OnInit<% if(!!viewEncapsulation) { %>, ViewEncapsulation<% }%><% if(changeDetection !== 'Default') { %>, ChangeDetectionStrategy<% }%> } from '@angular/core';
22

33
@Component({<% if(!skipSelector) {%>
4-
selector: '<%= selector %>',<%}%><% if(inlineTemplate) { %>
4+
selector: '<%= selector %>',<%}%><% if(standalone) {%>
5+
standalone: true,<%}%><% if(inlineTemplate) { %>
56
template: `
67
<p>
78
<%= dasherize(name) %> works!

packages/schematics/angular/component/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,12 @@ export default function (options: ComponentOptions): Rule {
155155
: noop(),
156156
move(parsedPath.path),
157157
]);
158+
const rules = [mergeWith(templateSource)];
158159

159-
return chain([addDeclarationToNgModule(options), mergeWith(templateSource)]);
160+
if (!options.standalone) {
161+
rules.unshift(addDeclarationToNgModule(options));
162+
}
163+
164+
return chain(rules);
160165
};
161166
}

packages/schematics/angular/component/index_spec.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,4 +420,14 @@ describe('Component Schematic', () => {
420420
expect(content).toMatch(/template: `(\n(.|)*){3}\n\s*`,\n/);
421421
expect(content).toMatch(/changeDetection: ChangeDetectionStrategy.OnPush/);
422422
});
423+
424+
it('should create a standalone component', async () => {
425+
const options = { ...defaultOptions, standalone: true };
426+
const tree = await schematicRunner.runSchematicAsync('component', options, appTree).toPromise();
427+
const moduleContent = tree.readContent('/projects/bar/src/app/app.module.ts');
428+
const componentContent = tree.readContent('/projects/bar/src/app/foo/foo.component.ts');
429+
expect(componentContent).toContain('standalone: true');
430+
expect(componentContent).toContain('class FooComponent');
431+
expect(moduleContent).not.toContain('FooComponent');
432+
});
423433
});

packages/schematics/angular/component/schema.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@
4848
"alias": "t",
4949
"x-user-analytics": 10
5050
},
51+
"standalone": {
52+
"description": "Whether the generated component is standalone.",
53+
"type": "boolean",
54+
"default": false,
55+
"alias": "sa",
56+
"x-user-analytics": 10
57+
},
5158
"viewEncapsulation": {
5259
"description": "The view encapsulation strategy to use in the new component.",
5360
"enum": ["Emulated", "None", "ShadowDom"],

packages/schematics/angular/directive/files/__name@dasherize@if-flat__/__name@dasherize__.directive.ts.template

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { Directive } from '@angular/core';
22

33
@Directive({
4-
selector: '[<%= selector %>]'
4+
selector: '[<%= selector %>]'<% if(standalone) {%>,
5+
standalone: true<%}%>
56
})
67
export class <%= classify(name) %>Directive {
78

packages/schematics/angular/directive/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,12 @@ export default function (options: DirectiveOptions): Rule {
134134
}),
135135
move(parsedPath.path),
136136
]);
137+
const rules = [mergeWith(templateSource)];
137138

138-
return chain([addDeclarationToNgModule(options), mergeWith(templateSource)]);
139+
if (!options.standalone) {
140+
rules.unshift(addDeclarationToNgModule(options));
141+
}
142+
143+
return chain(rules);
139144
};
140145
}

packages/schematics/angular/directive/index_spec.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,4 +183,14 @@ describe('Directive Schematic', () => {
183183
expect(files).toContain('/projects/bar/src/app/foo.directive.ts');
184184
expect(files).not.toContain('/projects/bar/src/app/foo.directive.spec.ts');
185185
});
186+
187+
it('should create a standalone directive', async () => {
188+
const options = { ...defaultOptions, standalone: true };
189+
const tree = await schematicRunner.runSchematicAsync('directive', options, appTree).toPromise();
190+
const moduleContent = tree.readContent('/projects/bar/src/app/app.module.ts');
191+
const directiveContent = tree.readContent('/projects/bar/src/app/foo.directive.ts');
192+
expect(directiveContent).toContain('standalone: true');
193+
expect(directiveContent).toContain('class FooDirective');
194+
expect(moduleContent).not.toContain('FooDirective');
195+
});
186196
});

packages/schematics/angular/directive/schema.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@
5959
"format": "html-selector",
6060
"description": "The HTML selector to use for this directive."
6161
},
62+
"standalone": {
63+
"description": "Whether the generated directive is standalone.",
64+
"type": "boolean",
65+
"default": false,
66+
"alias": "sa",
67+
"x-user-analytics": 10
68+
},
6269
"flat": {
6370
"type": "boolean",
6471
"description": "When true (the default), creates the new files at the top level of the current project.",

packages/schematics/angular/pipe/files/__name@dasherize@if-flat__/__name@dasherize__.pipe.ts.template

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { Pipe, PipeTransform } from '@angular/core';
22

33
@Pipe({
4-
name: '<%= camelize(name) %>'
4+
name: '<%= camelize(name) %>'<% if(standalone) {%>,
5+
standalone: true<%}%>
56
})
67
export class <%= classify(name) %>Pipe implements PipeTransform {
78

packages/schematics/angular/pipe/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,12 @@ export default function (options: PipeOptions): Rule {
111111
}),
112112
move(parsedPath.path),
113113
]);
114+
const rules = [mergeWith(templateSource)];
114115

115-
return chain([addDeclarationToNgModule(options), mergeWith(templateSource)]);
116+
if (!options.standalone) {
117+
rules.unshift(addDeclarationToNgModule(options));
118+
}
119+
120+
return chain(rules);
116121
};
117122
}

0 commit comments

Comments
 (0)