Rails-inspired generator system that provides scaffolding for your apps
The foundational Generator class and lifecycle management system that orchestrates the entire scaffolding process through predefined execution queues.
The main Generator class that extends BaseGenerator with simple-git integration.
/**
* Main Generator class that provides the complete API for building scaffolding tools
*/
export default class Generator<
O extends BaseOptions = BaseOptions,
F extends BaseFeatures = BaseFeatures
> extends BaseGenerator<O, F> {
constructor(options: O, features?: F);
constructor(args: string[], options: O, features?: F);
// Core properties
readonly options: O;
readonly env: Environment;
readonly fs: MemFsEditor;
readonly log: Logger;
readonly args: string[];
readonly appname: string;
readonly config: Storage;
readonly packageJson: Storage;
readonly yoGeneratorVersion: string;
readonly _destinationRoot: string;
readonly _sourceRoot: string;
// Git integration (specific to main Generator class)
readonly simpleGit: SimpleGit;
}Usage Example:
import Generator from "yeoman-generator";
export default class MyGenerator extends Generator {
constructor(args, opts) {
super(args, opts);
// Access generator properties
console.log(this.appname); // Determined app name
console.log(this.yoGeneratorVersion); // Generator version
console.log(this.destinationRoot()); // Current destination
}
}The foundational generator class providing the complete API surface.
/**
* Base generator class that provides the complete scaffolding API
*/
class BaseGenerator<O extends BaseOptions = BaseOptions, F extends BaseFeatures = BaseFeatures>
extends EventEmitter {
constructor(options: O, features?: F);
constructor(args: string[], options: O, features?: F);
// Core properties
readonly options: O;
readonly _initOptions: O;
readonly _args: string[];
readonly _namespace: string;
readonly resolved: string;
description: string;
readonly env: Environment;
readonly fs: MemFsEditor;
readonly log: Logger;
readonly args: string[];
readonly appname: string;
readonly yoGeneratorVersion: string;
// Configuration storage
readonly config: Storage;
readonly packageJson: Storage;
generatorConfig?: Storage;
instanceConfig?: Storage;
// Core methods
run(): Promise<void>;
debug(formatter: any, ...args: any[]): void;
setFeatures(features: F): void;
getFeatures(): F;
checkEnvironmentVersion(version: string, warning?: boolean): boolean | undefined;
rootGeneratorName(): string;
rootGeneratorVersion(): string;
createStorage(storePath: string, options?: string | StorageOptions): Storage;
}The predefined execution order for generator methods.
/**
* Static queue names that define the execution order of generator methods
*/
static readonly queues: readonly [
'initializing',
'prompting',
'configuring',
'default',
'writing',
'transform',
'conflicts',
'install',
'end'
];Usage Example:
export default class MyGenerator extends Generator {
// Methods named after queues run in predefined order
initializing() {
// Setup and initialization
this.log('Initializing generator...');
}
async prompting() {
// User prompts
this.answers = await this.prompt([...]);
}
configuring() {
// Save configurations
this.config.set('answers', this.answers);
}
writing() {
// Write files
this.renderTemplate('template.ejs', 'output.js', this.answers);
}
install() {
// Install dependencies
this.spawnCommand('npm', ['install']);
}
end() {
// Final cleanup and messages
this.log('Generator complete!');
}
}Methods for managing source templates and destination paths.
/**
* Get or set the generator destination root directory
* @param rootPath - New destination root path
* @returns Current destination root path
*/
destinationRoot(rootPath?: string): string;
/**
* Get or set the generator source root directory
* @param rootPath - New source root path
* @returns Current source root path
*/
sourceRoot(rootPath?: string): string;
/**
* Join paths to the destination root
* @param dest - Path parts to join
* @returns Joined path to destination
*/
destinationPath(...dest: string[]): string;
/**
* Join paths to the source root (template path)
* @param dest - Path parts to join
* @returns Joined path to template
*/
templatePath(...dest: string[]): string;Usage Example:
export default class MyGenerator extends Generator {
constructor(args, opts) {
super(args, opts);
// Set custom template location
this.sourceRoot(path.join(__dirname, 'templates'));
}
writing() {
// Use path helpers
const templateFile = this.templatePath('app', 'index.js');
const outputFile = this.destinationPath('src', 'index.js');
this.fs.copy(templateFile, outputFile);
}
}Automatically determine the application name from package.json or directory.
/**
* Determines the name of the application
* First checks for name in package.json, then defaults to directory name
* @returns The determined application name
*/
determineAppname(): string;Methods for accessing generator information.
/**
* Determine the root generator name (the one extending Generator)
* @returns The name of the root generator
*/
rootGeneratorName(): string;
/**
* Determine the root generator version (the one extending Generator)
* @returns The version of the root generator
*/
rootGeneratorVersion(): string;Validate that the yeoman-environment version meets requirements.
/**
* Check that the environment version meets minimum requirements
* @param version - Required version string
* @param warning - Whether to show warning instead of throwing error
* @returns Whether version check passed
*/
checkEnvironmentVersion(version: string, warning?: boolean): boolean | undefined;
checkEnvironmentVersion(packageDependency: string, version: string, warning?: boolean): boolean | undefined;Configure generator behaviors and capabilities.
/**
* Configure Generator behaviors
* @param features - Feature configuration object
*/
setFeatures(features: F): void;
/**
* Get current feature configuration
* @returns Current features
*/
getFeatures(): F;Usage Example:
export default class MyGenerator extends Generator {
constructor(args, opts) {
super(args, opts);
// Configure generator features
this.setFeatures({
unique: 'namespace', // Only one instance per namespace
customPriorities: [
{ priorityName: 'setup', before: 'prompting' }
]
});
}
}interface BaseOptions {
destinationRoot?: string;
skipInstall?: boolean;
skipCheckEnv?: boolean;
ignoreVersionCheck?: boolean;
askAnswered?: boolean;
localConfigOnly?: boolean;
skipCache?: boolean;
skipLocalCache?: boolean;
description?: string;
skipParseOptions?: boolean;
customPriorities?: Priority[];
}
interface BaseFeatures {
uniqueBy?: string;
unique?: true | 'argument' | 'namespace';
tasksMatchingPriority?: boolean;
taskPrefix?: string;
customInstallTask?: boolean | ((...args: any[]) => void | Promise<void>);
customCommitTask?: boolean | ((...args: any[]) => void | Promise<void>);
skipParseOptions?: boolean;
customPriorities?: Priority[];
inheritTasks?: boolean;
}Install with Tessl CLI
npx tessl i tessl/npm-yeoman-generator