Micro-generator framework that makes it easy for an entire team to create files with a level of uniformity
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Plop provides a comprehensive programmatic API for creating, configuring, and executing code generators. This API is primarily provided by the node-plop package that plop re-exports.
Create a new plop API instance for programmatic generator management.
/**
* Create a new NodePlopAPI instance
* @param plopfilePath - Optional absolute path to plopfile
* @param plopCfg - Optional configuration object
* @returns Promise resolving to NodePlopAPI instance
*/
function nodePlop(plopfilePath?: string, plopCfg?: PlopCfg): Promise<NodePlopAPI>;
interface PlopCfg {
force?: boolean; // Force overwrite existing files
destBasePath?: string; // Base path for file operations
}Usage Examples:
import { nodePlop } from "plop";
// Create instance without plopfile
const plop = await nodePlop();
// Create instance with specific plopfile
const plop = await nodePlop('/path/to/plopfile.js');
// Create instance with configuration
const plop = await nodePlop('./plopfile.js', {
force: true,
destBasePath: './output'
});Create and manage code generators programmatically.
/**
* Register a new generator with the plop instance
* @param name - Unique generator name
* @param config - Generator configuration object
* @returns PlopGenerator instance
*/
setGenerator(name: string, config: Partial<PlopGeneratorConfig>): PlopGenerator;
/**
* Retrieve a registered generator by name
* @param name - Generator name
* @returns PlopGenerator instance or undefined
*/
getGenerator(name: string): PlopGenerator;
/**
* Get list of all registered generators
* @returns Array of generator info objects
*/
getGeneratorList(): { name: string; description: string }[];Generator Configuration:
interface PlopGeneratorConfig {
description: string; // Human-readable description
prompts: Prompts; // Inquirer prompts or function
actions: Actions; // Actions to perform or function
}
type Prompts = DynamicPromptsFunction | PromptQuestion[];
type Actions = DynamicActionsFunction | ActionType[];Usage Examples:
import { nodePlop } from "plop";
const plop = await nodePlop();
// Register a component generator
const componentGen = plop.setGenerator('component', {
description: 'React component generator',
prompts: [
{
type: 'input',
name: 'name',
message: 'Component name:'
},
{
type: 'list',
name: 'type',
message: 'Component type:',
choices: ['functional', 'class']
}
],
actions: [
{
type: 'add',
path: 'src/components/{{name}}.jsx',
templateFile: 'templates/component.hbs'
}
]
});
// Get generator by name
const gen = plop.getGenerator('component');
// List all generators
const generators = plop.getGeneratorList();
console.log(generators);
// [{ name: 'component', description: 'React component generator' }]Execute generators programmatically with prompt handling and action processing.
interface PlopGenerator extends PlopGeneratorConfig {
/**
* Run generator prompts and collect user input
* @param bypassArr - Optional array to bypass prompts with pre-filled answers
* @returns Promise resolving to user answers
*/
runPrompts(bypassArr?: string[]): Promise<any>;
/**
* Execute generator actions with provided answers
* @param answers - Answers from prompts or provided data
* @param hooks - Optional lifecycle hooks
* @returns Promise resolving to execution results
*/
runActions(answers: Answers, hooks?: PlopActionHooks): Promise<{
changes: PlopActionHooksChanges[];
failures: PlopActionHooksFailures[];
}>;
}Action Hooks Interface:
interface PlopActionHooks {
onComment?: (msg: string) => void;
onSuccess?: (change: PlopActionHooksChanges) => void;
onFailure?: (failure: PlopActionHooksFailures) => void;
}
interface PlopActionHooksChanges {
type: string; // Action type that succeeded
path: string; // File path that was changed
}
interface PlopActionHooksFailures {
type: string; // Action type that failed
path: string; // File path that failed
error: string; // Error message
message: string; // Human-readable message
}Usage Examples:
const plop = await nodePlop('./plopfile.js');
const generator = plop.getGenerator('component');
// Run with interactive prompts
const answers = await generator.runPrompts();
// Run with bypass data (skip prompts)
const answers = await generator.runPrompts(['MyComponent', 'functional']);
// Execute actions with hooks
const results = await generator.runActions(answers, {
onSuccess: (change) => console.log(`✅ ${change.type}: ${change.path}`),
onFailure: (failure) => console.error(`❌ ${failure.type}: ${failure.error}`),
onComment: (msg) => console.log(`💬 ${msg}`)
});
console.log(`${results.changes.length} files changed`);
console.log(`${results.failures.length} failures`);Use functions to dynamically configure prompts and actions based on runtime conditions.
/**
* Function that returns prompts dynamically
* @param inquirer - Inquirer instance for advanced prompt handling
* @returns Promise resolving to prompt answers
*/
type DynamicPromptsFunction = (inquirer: Inquirer) => Promise<Answers>;
/**
* Function that returns actions dynamically based on answers
* @param data - Answers from prompts
* @returns Array of actions to execute
*/
type DynamicActionsFunction = (data?: Answers) => ActionType[];Usage Examples:
plop.setGenerator('advanced', {
description: 'Advanced generator with dynamic configuration',
// Dynamic prompts based on conditions
prompts: async (inquirer) => {
const answers = {};
// Conditional prompting
answers.type = await inquirer.prompt({
type: 'list',
name: 'type',
choices: ['api', 'ui', 'test']
});
if (answers.type === 'api') {
answers.methods = await inquirer.prompt({
type: 'checkbox',
name: 'methods',
choices: ['GET', 'POST', 'PUT', 'DELETE']
});
}
return answers;
},
// Dynamic actions based on answers
actions: (data) => {
const actions = [
{
type: 'add',
path: `src/${data.type}/{{name}}.js`,
templateFile: `templates/${data.type}.hbs`
}
];
if (data.type === 'api' && data.methods.includes('POST')) {
actions.push({
type: 'add',
path: `src/${data.type}/{{name}}.test.js`,
templateFile: 'templates/api-test.hbs'
});
}
return actions;
}
});Control file system paths and destination handling.
/**
* Set the path to the plopfile for this instance
* @param filePath - Absolute path to plopfile
*/
setPlopfilePath(filePath: string): void;
/**
* Get the current plopfile path
* @returns Current plopfile path
*/
getPlopfilePath(): string;
/**
* Get the base destination path for file operations
* @returns Base destination path
*/
getDestBasePath(): string;Render Handlebars templates with data outside of action context.
/**
* Render a Handlebars template string with provided data
* @param template - Handlebars template string
* @param data - Data object for template rendering
* @returns Rendered string
*/
renderString(template: string, data: any): string;Usage Examples:
const plop = await nodePlop();
// Render template with data
const template = 'Hello {{name}}, welcome to {{project}}!';
const rendered = plop.renderString(template, {
name: 'Alice',
project: 'My App'
});
console.log(rendered); // "Hello Alice, welcome to My App!"
// Use with path templates
const pathTemplate = 'src/components/{{kebabCase name}}/{{pascalCase name}}.jsx';
const path = plop.renderString(pathTemplate, { name: 'MyComponent' });
console.log(path); // "src/components/my-component/MyComponent.jsx"Install with Tessl CLI
npx tessl i tessl/npm-plop