| name | nx-generator-creator |
| description | Create new Nx workspace plugin generators using RxAP utilities. Use this skill when you need to scaffold and implement generators for creating application code (NestJS services, Angular components, etc.). |
Nx Generator Creator
This skill guides you through the process of creating a new Nx workspace generator. The goal is to create generators that produce application code using standard patterns and utilities.
Process
1. Scaffold the Generator
Use the Nx CLI to create the initial generator structure.
nx generate @nx/plugin:generator --name=<generator-name> --project=<plugin-project>
2. Implementation Strategy
Your generator should primarily use ts-morph for code generation and modification. Avoid using string templates (.template files) for complex TypeScript files.
Core Pattern:
- Read/Check: Use
@rxap/workspace-utilities to check for project existence, read configuration, etc.
- Dependencies: Use
AddPackageJsonDependency to add required packages.
- Transform: Use
@rxap/workspace-ts-morph to modify or create TypeScript files via AST.
3. Using Utilities
Refer to Utilities Reference for a comprehensive list of available functions.
Common Workflow
Example: Creating a NestJS Module
import { Tree } from '@nx/devkit';
import { TsMorphNestProjectTransform } from '@rxap/workspace-ts-morph';
import { CoerceNestModule } from '@rxap/ts-morph';
export default async function (tree: Tree, options: any) {
await TsMorphNestProjectTransform(
tree,
{
project: options.project,
backend: undefined
},
(project, [moduleSourceFile]) => {
CoerceNestModule(moduleSourceFile, {
name: options.name
});
},
['src/app/my-feature/my-feature.module.ts']
);
}
Example: Creating an Angular Component
import { Tree } from '@nx/devkit';
import { TsMorphAngularProjectTransform } from '@rxap/workspace-ts-morph';
import { CoerceComponent } from '@rxap/ts-morph';
export default async function (tree: Tree, options: any) {
await TsMorphAngularProjectTransform(
tree,
{ project: options.project },
(project, [sourceFile]) => {
CoerceComponent(sourceFile, options.name, {
selector: 'app-' + options.name,
templateUrl: true,
styleUrls: true
});
},
[`src/app/${options.name}/${options.name}.component.ts`]
);
}
Best Practices
- Coercion: Prefer
Coerce... functions over Add... functions. Coercion implies "create if missing, update if exists", which is idempotent and safer.
- Exact Imports: When using
CoerceImports, provide the exact namedImports and moduleSpecifier.
- AST over Templates: Use
ts-morph for logic, imports, and class structures. Use templates only for static assets (HTML, SCSS, JSON).