0
# Generators & Code Generation
1
2
Tools for creating code generators that scaffold projects, components, and features with template-based file generation. Generators use the virtual Tree interface to batch file operations and provide callback mechanisms for post-generation tasks.
3
4
## Capabilities
5
6
### Core Generator Functions
7
8
Essential functions for file generation and formatting.
9
10
```typescript { .api }
11
/**
12
* Format all files in the tree using Prettier
13
* @param tree - Virtual file system tree
14
* @returns Promise that resolves when formatting is complete
15
*/
16
function formatFiles(tree: Tree): Promise<void>;
17
18
/**
19
* Generate files from templates with variable substitution
20
* @param tree - Virtual file system tree to write to
21
* @param srcFolder - Source folder containing template files
22
* @param target - Target directory for generated files
23
* @param substitutions - Variables for template substitution
24
* @param options - Optional generation options
25
*/
26
function generateFiles(
27
tree: Tree,
28
srcFolder: string,
29
target: string,
30
substitutions: Record<string, any>,
31
options?: GenerateFilesOptions
32
): void;
33
34
/**
35
* Convert TypeScript files to JavaScript
36
* @param tree - Virtual file system tree
37
* @param options - Conversion options
38
*/
39
function toJS(tree: Tree, options?: ToJSOptions): void;
40
41
/**
42
* Update TypeScript configurations for JavaScript compilation
43
* @param tree - Virtual file system tree
44
* @param options - Update options
45
*/
46
function updateTsConfigsToJs(tree: Tree, options?: { projectRoot: string }): void;
47
48
/**
49
* Execute generator callbacks in sequence
50
* @param callbacks - Array of generator callbacks to execute
51
* @returns Promise that resolves when all callbacks complete
52
*/
53
function runTasksInSerial(...callbacks: GeneratorCallback[]): Promise<void>;
54
```
55
56
**Usage Examples:**
57
58
```typescript
59
import {
60
Tree,
61
generateFiles,
62
formatFiles,
63
names
64
} from "@nrwl/devkit";
65
import * as path from "path";
66
67
export default async function myGenerator(tree: Tree, schema: any) {
68
// Generate files from templates
69
generateFiles(
70
tree,
71
path.join(__dirname, 'files'), // Template directory
72
schema.projectRoot,
73
{
74
...schema,
75
...names(schema.name),
76
template: '' // Remove .template suffix from file names
77
}
78
);
79
80
// Format all generated files
81
await formatFiles(tree);
82
}
83
```
84
85
### Generator Types
86
87
Core interfaces and types for creating generators.
88
89
```typescript { .api }
90
/**
91
* Generator function signature
92
* @template T - Schema type for generator options
93
*/
94
type Generator<T = any> = (
95
tree: Tree,
96
schema: T
97
) => void | GeneratorCallback | Promise<void | GeneratorCallback>;
98
99
/**
100
* Callback function executed after filesystem changes are applied
101
*/
102
type GeneratorCallback = () => void | Promise<void>;
103
104
/**
105
* Configuration for generators.json files
106
*/
107
interface GeneratorsJson {
108
extends?: string;
109
schematics?: Record<string, GeneratorConfiguration>;
110
generators?: Record<string, GeneratorConfiguration>;
111
}
112
113
/**
114
* Configuration for a single generator
115
*/
116
interface GeneratorConfiguration {
117
factory: string;
118
schema: string;
119
aliases?: string[];
120
hidden?: boolean;
121
description?: string;
122
}
123
124
/**
125
* Strategy for handling existing files during generation
126
*/
127
enum OverwriteStrategy {
128
/**
129
* Throw an error if file exists
130
*/
131
ThrowIfExisting = 'ThrowIfExisting',
132
/**
133
* Overwrite existing files
134
*/
135
Overwrite = 'Overwrite',
136
/**
137
* Skip files that already exist
138
*/
139
SkipIfExisting = 'SkipIfExisting'
140
}
141
142
/**
143
* Options for file generation
144
*/
145
interface GenerateFilesOptions {
146
/** Strategy for handling existing files */
147
overwriteStrategy?: OverwriteStrategy;
148
}
149
150
/**
151
* Options for TypeScript to JavaScript conversion
152
*/
153
interface ToJSOptions {
154
extension?: '.js' | '.mjs' | '.cjs';
155
errors?: 'warn' | 'ignore';
156
}
157
```
158
159
**Usage Examples:**
160
161
```typescript
162
import { Tree, Generator, GeneratorCallback } from "@nrwl/devkit";
163
164
interface Schema {
165
name: string;
166
directory?: string;
167
skipTests?: boolean;
168
}
169
170
const myGenerator: Generator<Schema> = async (tree: Tree, options: Schema) => {
171
// Generate files
172
generateFiles(tree, __dirname + '/files', options.directory || '.', options);
173
174
// Return a callback for post-generation tasks
175
const callback: GeneratorCallback = async () => {
176
console.log('Generator completed successfully!');
177
};
178
179
return callback;
180
};
181
182
export default myGenerator;
183
```
184
185
### Template File Generation
186
187
Advanced file generation with template processing and naming conventions.
188
189
```typescript { .api }
190
/**
191
* Generate files from templates with advanced options
192
* @param tree - Virtual file system tree
193
* @param srcFolder - Template source directory
194
* @param target - Target output directory
195
* @param substitutions - Template variables and options
196
*/
197
function generateFiles(
198
tree: Tree,
199
srcFolder: string,
200
target: string,
201
substitutions: Record<string, any> & {
202
template?: string;
203
dot?: string;
204
tmpl?: string;
205
}
206
): void;
207
```
208
209
**Template File Examples:**
210
211
Template files use EJS syntax for variable substitution:
212
213
```typescript
214
// files/src/lib/__name__.ts.template
215
export class <%= className %> {
216
constructor(private config: <%= className %>Config) {}
217
218
<% if (includeAsyncMethods) { %>
219
async initialize(): Promise<void> {
220
// Async initialization logic
221
}
222
<% } %>
223
}
224
```
225
226
```typescript
227
// Generator usage
228
generateFiles(tree, path.join(__dirname, 'files'), projectRoot, {
229
...options,
230
...names(options.name),
231
template: '', // Removes .template extension
232
dot: '.', // Converts __dot__ to .
233
includeAsyncMethods: options.async
234
});
235
```
236
237
### Name Utilities
238
239
Utility functions for generating consistent naming conventions.
240
241
```typescript { .api }
242
/**
243
* Generate various name formats from a base name
244
* @param name - Base name to transform
245
* @returns Object with different name formats
246
*/
247
function names(name: string): {
248
/** Original name as provided */
249
name: string;
250
/** PascalCase class name */
251
className: string;
252
/** camelCase property name */
253
propertyName: string;
254
/** CONSTANT_CASE name */
255
constantName: string;
256
/** kebab-case file name */
257
fileName: string;
258
};
259
```
260
261
**Usage Examples:**
262
263
```typescript
264
import { names } from "@nrwl/devkit";
265
266
const nameFormats = names('my-awesome-feature');
267
console.log(nameFormats);
268
// Output:
269
// {
270
// name: 'my-awesome-feature',
271
// className: 'MyAwesomeFeature',
272
// propertyName: 'myAwesomeFeature',
273
// constantName: 'MY_AWESOME_FEATURE',
274
// fileName: 'my-awesome-feature'
275
// }
276
```
277
278
### Conversion Utilities
279
280
Functions for converting between different module formats and build systems.
281
282
```typescript { .api }
283
/**
284
* Convert Nx generator to Angular schematic format
285
* @param generator - Nx generator function
286
* @returns Angular schematic factory function
287
*/
288
function convertNxGenerator<T = any>(generator: Generator<T>): any;
289
290
/**
291
* Convert Nx executor to Angular builder format
292
* @param executor - Nx executor function
293
* @returns Angular builder function
294
*/
295
function convertNxExecutor<T = any>(executor: Executor<T>): any;
296
```
297
298
**Usage Examples:**
299
300
```typescript
301
import { convertNxGenerator, Generator } from "@nrwl/devkit";
302
303
const myGenerator: Generator = (tree, options) => {
304
// Generator implementation
305
};
306
307
// Convert for use with Angular CLI
308
export const schematic = convertNxGenerator(myGenerator);
309
```