or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

executors.mdgenerators.mdindex.mdpackage-management.mdplugin-development.mdproject-graph.mdtree-operations.mdutilities.mdworkspace-configuration.md

generators.mddocs/

0

# Code Generation

1

2

Powerful code generation utilities for creating files from templates, formatting code, and managing project scaffolding with EJS templating support.

3

4

## Capabilities

5

6

### File Generation from Templates

7

8

Generate files and directories from template folders with variable substitution and conditional logic.

9

10

```typescript { .api }

11

/**

12

* Generates a folder of files based on provided templates

13

* Performs template substitutions using EJS and filename replacements

14

* @param tree - File system tree

15

* @param srcFolder - Source template folder (absolute path)

16

* @param target - Target directory relative to workspace root

17

* @param substitutions - Variables for template substitution

18

* @param options - Generation options including overwrite strategy

19

*/

20

function generateFiles(

21

tree: Tree,

22

srcFolder: string,

23

target: string,

24

substitutions: { [k: string]: any },

25

options?: GenerateFilesOptions

26

): void;

27

28

interface GenerateFilesOptions {

29

/** Strategy for handling existing files */

30

overwriteStrategy?: OverwriteStrategy;

31

}

32

33

enum OverwriteStrategy {

34

/** Replace existing files */

35

Overwrite = "overwrite",

36

/** Keep existing files unchanged */

37

KeepExisting = "keepExisting",

38

/** Throw error if file exists */

39

ThrowIfExisting = "throwIfExisting"

40

}

41

```

42

43

**Usage Examples:**

44

45

```typescript

46

import { Tree, generateFiles, OverwriteStrategy } from "@nx/devkit";

47

import * as path from "path";

48

49

export default function myGenerator(tree: Tree, options: { name: string; description?: string }) {

50

// Generate files from templates with substitutions

51

generateFiles(

52

tree,

53

path.join(__dirname, "files"), // Template source folder

54

`libs/${options.name}`, // Target directory

55

{

56

...options,

57

tmpl: "", // Remove __tmpl__ suffix from filenames

58

className: options.name.charAt(0).toUpperCase() + options.name.slice(1),

59

},

60

{

61

overwriteStrategy: OverwriteStrategy.ThrowIfExisting

62

}

63

);

64

}

65

66

// Template structure example:

67

// files/

68

// src/

69

// index.ts__tmpl__

70

// lib/

71

// __name__.ts__tmpl__

72

// README.md__tmpl__

73

// package.json__tmpl__

74

75

// Template file content example (index.ts__tmpl__):

76

/*

77

export * from './lib/<%= name %>';

78

79

// Generated with className: <%= className %>

80

// Description: <%= description || 'No description provided' %>

81

*/

82

```

83

84

### Code Formatting

85

86

Format generated code using Prettier and other formatting tools.

87

88

```typescript { .api }

89

/**

90

* Formats all created or updated files using Prettier

91

* Only formats if Prettier is detected in the workspace

92

* @param tree - File system tree

93

* @param options - Formatting options

94

*/

95

function formatFiles(

96

tree: Tree,

97

options?: {

98

sortRootTsconfigPaths?: boolean;

99

}

100

): Promise<void>;

101

```

102

103

**Usage Examples:**

104

105

```typescript

106

import { Tree, generateFiles, formatFiles } from "@nx/devkit";

107

108

export default async function myGenerator(tree: Tree, options: any) {

109

// Generate files

110

generateFiles(tree, templatePath, targetPath, substitutions);

111

112

// Format all generated files

113

await formatFiles(tree, {

114

sortRootTsconfigPaths: true // Sort paths in tsconfig.json

115

});

116

}

117

```

118

119

### TypeScript to JavaScript Conversion

120

121

Convert TypeScript files to JavaScript and update configurations accordingly.

122

123

```typescript { .api }

124

/**

125

* Rename and transpile TypeScript files to JavaScript

126

* @param tree - File system tree

127

* @param options - Conversion options

128

*/

129

function toJS(tree: Tree, options?: ToJSOptions): void;

130

131

/**

132

* Update TypeScript configurations to allow JavaScript files

133

* @param tree - File system tree

134

* @param options - Configuration options

135

*/

136

function updateTsConfigsToJs(

137

tree: Tree,

138

options: { projectRoot: string }

139

): void;

140

141

interface ToJSOptions {

142

/** Convert all files in the tree */

143

all?: boolean;

144

/** Specific files to convert */

145

files?: string[];

146

}

147

```

148

149

**Usage Examples:**

150

151

```typescript

152

import { Tree, toJS, updateTsConfigsToJs } from "@nx/devkit";

153

154

export default function convertToJs(tree: Tree, options: { projectRoot: string }) {

155

// Convert TypeScript files to JavaScript

156

toJS(tree);

157

158

// Update tsconfig files to allow JS

159

updateTsConfigsToJs(tree, {

160

projectRoot: options.projectRoot

161

});

162

}

163

```

164

165

### Task Management

166

167

Manage and sequence generator callbacks for post-generation tasks.

168

169

```typescript { .api }

170

/**

171

* Run multiple generator callbacks in sequence

172

* @param tasks - Array of callback functions to execute

173

* @returns Combined callback that runs all tasks in order

174

*/

175

function runTasksInSerial(...tasks: GeneratorCallback[]): GeneratorCallback;

176

177

/**

178

* Callback function type returned by generators

179

* Used for post-generation tasks like installing packages

180

*/

181

type GeneratorCallback = () => void | Promise<void>;

182

```

183

184

**Usage Examples:**

185

186

```typescript

187

import {

188

Tree,

189

GeneratorCallback,

190

runTasksInSerial,

191

addDependenciesToPackageJson,

192

installPackagesTask

193

} from "@nx/devkit";

194

195

export default function myGenerator(tree: Tree, options: any): GeneratorCallback {

196

// Generate files...

197

198

// Create multiple tasks

199

const addDepsTask = addDependenciesToPackageJson(

200

tree,

201

{ react: "^18.0.0" },

202

{ "@types/react": "^18.0.0" }

203

);

204

205

const installTask = () => installPackagesTask(tree);

206

207

const customTask = () => {

208

console.log("Running custom post-generation task");

209

};

210

211

// Return combined task that runs in sequence

212

return runTasksInSerial(addDepsTask, installTask, customTask);

213

}

214

```

215

216

### File Processing Utilities

217

218

Utilities for processing files and handling ignored files.

219

220

```typescript { .api }

221

/**

222

* Visit all files that are not ignored by git

223

* @param tree - File system tree

224

* @param dirPath - Directory to visit (defaults to root)

225

* @param visitor - Function called for each non-ignored file

226

*/

227

function visitNotIgnoredFiles(

228

tree: Tree,

229

dirPath?: string,

230

visitor: (path: string) => void

231

): void;

232

```

233

234

**Usage Examples:**

235

236

```typescript

237

import { Tree, visitNotIgnoredFiles } from "@nx/devkit";

238

239

export default function processFiles(tree: Tree) {

240

// Process all non-ignored TypeScript files

241

visitNotIgnoredFiles(tree, "src", (filePath) => {

242

if (filePath.endsWith(".ts") && !filePath.endsWith(".spec.ts")) {

243

const content = tree.read(filePath, "utf-8");

244

// Process the file content

245

const processedContent = content.replace(/old-pattern/g, "new-pattern");

246

tree.write(filePath, processedContent);

247

}

248

});

249

}

250

```

251

252

## Generator Types

253

254

### Core Generator Interface

255

256

```typescript { .api }

257

/**

258

* Generator function signature

259

* Can return void, a callback, or a promise of either

260

*/

261

type Generator<T = any> = (

262

tree: Tree,

263

schema: T

264

) => void | GeneratorCallback | Promise<void | GeneratorCallback>;

265

266

/**

267

* Migration function signature for updating existing code

268

*/

269

type Migration<T = any> = (

270

tree: Tree,

271

schema: T

272

) => void | GeneratorCallback | Promise<void | GeneratorCallback>;

273

274

/**

275

* Schema definition for generators.json

276

*/

277

interface GeneratorsJson {

278

generators?: Record<string, GeneratorDescription>;

279

schematics?: Record<string, GeneratorDescription>; // Legacy support

280

}

281

282

interface GeneratorDescription {

283

/** Path to the generator implementation */

284

implementation?: string;

285

/** Path to the schema JSON file */

286

schema?: string;

287

/** Aliases for the generator */

288

aliases?: string[];

289

/** Whether generator is hidden from help */

290

hidden?: boolean;

291

/** Description of the generator */

292

description?: string;

293

}

294

```

295

296

### Template Substitution

297

298

The `generateFiles` function supports EJS templating with these features:

299

300

**Filename Substitution:**

301

- `__name__` → replaced with `substitutions.name`

302

- `__className__` → replaced with `substitutions.className`

303

- `__tmpl__` → removed (use `tmpl: ""` in substitutions)

304

305

**Content Substitution:**

306

- `<%= variable %>` → outputs variable value

307

- `<%- variable %>` → outputs unescaped variable value

308

- `<% if (condition) { %>...content...<% } %>` → conditional content

309

- `<% for (item of items) { %>...content...<% } %>` → loops

310

311

**Advanced Usage Examples:**

312

313

```typescript

314

// Template file: __name__.service.ts__tmpl__

315

/*

316

<% if (type === 'api') { %>

317

import { Injectable } from '@angular/core';

318

import { HttpClient } from '@angular/common/http';

319

320

@Injectable({

321

providedIn: 'root'

322

})

323

export class <%= className %>Service {

324

constructor(private http: HttpClient) {}

325

326

<% for (method of methods) { %>

327

<%= method.name %>(<%- method.params %>): <%= method.returnType %> {

328

return this.http.<%= method.httpMethod %>('/<%= name %>/<%= method.endpoint %>');

329

}

330

331

<% } %>

332

}

333

<% } else { %>

334

export class <%= className %>Service {

335

// Simple service implementation

336

}

337

<% } %>

338

*/

339

340

// Generator usage:

341

generateFiles(tree, templatePath, targetPath, {

342

name: 'user',

343

className: 'User',

344

type: 'api',

345

methods: [

346

{

347

name: 'getUsers',

348

params: '',

349

returnType: 'Observable<User[]>',

350

httpMethod: 'get',

351

endpoint: 'list'

352

},

353

{

354

name: 'createUser',

355

params: 'user: User',

356

returnType: 'Observable<User>',

357

httpMethod: 'post',

358

endpoint: 'create'

359

}

360

],

361

tmpl: ''

362

});

363

```

364

365

### Framework Integration

366

367

Converting Nx generators for use with other frameworks:

368

369

```typescript { .api }

370

/**

371

* Convert an Nx Generator to Angular Devkit Schematic

372

* @param generator - Nx generator function

373

* @param skipWritingConfigInOldFormat - Skip legacy format

374

* @returns Angular DevKit schematic

375

*/

376

function convertNxGenerator<T = any>(

377

generator: Generator<T>,

378

skipWritingConfigInOldFormat?: boolean

379

): any;

380

```

381

382

**Usage Examples:**

383

384

```typescript

385

import { convertNxGenerator } from "@nx/devkit";

386

387

// Convert Nx generator to Angular schematic

388

const schematic = convertNxGenerator(myNxGenerator);

389

390

// Use in Angular CLI collection

391

export default schematic;

392

```