Micro-generator framework that makes it easy for an entire team to create files with a level of uniformity
npx @tessl/cli install tessl/npm-plop@4.0.00
# Plop
1
2
Plop is a micro-generator framework that makes it easy for development teams to create files with consistent patterns and structures. It combines interactive command-line prompts with Handlebars templates to automate the generation of boilerplate code, components, routes, controllers, and other repetitive file structures. By codifying file creation patterns, Plop helps maintain coding standards and best practices across teams.
3
4
## Package Information
5
6
- **Package Name**: plop
7
- **Package Type**: npm
8
- **Language**: JavaScript (Node.js)
9
- **Installation**: `npm install -g plop` or `npm install --save-dev plop`
10
11
## Core Imports
12
13
For CLI programmatic usage:
14
15
```javascript
16
import { Plop, run } from "plop";
17
```
18
19
For advanced programmatic usage (direct node-plop access):
20
21
```javascript
22
import { nodePlop } from "plop";
23
// or
24
import nodePlop from "node-plop";
25
```
26
27
For CommonJS:
28
29
```javascript
30
const { Plop, run } = require("plop");
31
const { nodePlop } = require("plop");
32
```
33
34
For CLI usage, no imports needed - use the `plop` command directly.
35
36
## Basic Usage
37
38
### CLI Usage
39
40
```bash
41
# Install globally
42
npm install -g plop
43
44
# Run plop (shows generator list)
45
plop
46
47
# Run specific generator
48
plop component
49
50
# Run generator with bypass data
51
plop component "MyComponent"
52
```
53
54
### Programmatic Usage
55
56
```javascript
57
import { Plop, run } from "plop";
58
import path from "node:path";
59
60
// Prepare and execute plop programmatically
61
Plop.prepare({
62
cwd: process.cwd(),
63
configPath: path.join(__dirname, 'plopfile.js'),
64
}, env => Plop.execute(env, run));
65
```
66
67
## Architecture
68
69
Plop is built around several key components:
70
71
- **CLI Interface**: Primary user interaction through terminal commands with argument parsing and help system
72
- **Liftoff Integration**: Configuration file discovery and environment setup for finding plopfiles
73
- **Generator System**: Integration with node-plop for executing generators with prompts and actions
74
- **Progress Feedback**: Visual progress indicators using Ora spinners during file generation
75
- **Bypass System**: Allows skipping prompts by providing values directly via CLI arguments
76
77
## Capabilities
78
79
### Command Line Interface
80
81
Full-featured CLI for running generators interactively or with bypass data. Includes help system, version information, and initialization commands.
82
83
```javascript { .api }
84
// CLI entry point from bin/plop.js
85
import { Plop, run } from "../src/plop.js";
86
87
Plop.prepare(options, function (env) {
88
Plop.execute(env, run);
89
});
90
```
91
92
[Command Line Interface](./cli.md)
93
94
### Programmatic Execution
95
96
Core execution functions for embedding Plop functionality in custom tools and workflows.
97
98
```javascript { .api }
99
/**
100
* Main execution function for plop generators
101
* @param env - Environment object from Liftoff containing configuration
102
* @param _ - Unused parameter for compatibility
103
* @param passArgsBeforeDashes - Optional boolean to merge CLI and generator args
104
* @returns Promise resolving to plop instance
105
*/
106
async function run(env, _, passArgsBeforeDashes);
107
108
/**
109
* Liftoff instance configured for plop
110
*/
111
const Plop: Liftoff;
112
113
/**
114
* Ora spinner instance for progress indication
115
*/
116
const progressSpinner: ora.Ora;
117
```
118
119
[Programmatic Usage](./programmatic.md)
120
121
### Generator Management API
122
123
Comprehensive programmatic API for creating, configuring, and executing code generators through the node-plop package.
124
125
```javascript { .api }
126
/**
127
* Create a new NodePlopAPI instance
128
* @param plopfilePath - Optional absolute path to plopfile
129
* @param plopCfg - Optional configuration object
130
* @returns Promise resolving to NodePlopAPI instance
131
*/
132
function nodePlop(plopfilePath?: string, plopCfg?: PlopCfg): Promise<NodePlopAPI>;
133
134
/**
135
* Register a new generator
136
* @param name - Unique generator name
137
* @param config - Generator configuration
138
* @returns PlopGenerator instance
139
*/
140
setGenerator(name: string, config: Partial<PlopGeneratorConfig>): PlopGenerator;
141
142
/**
143
* Execute generator prompts and actions
144
* @param bypassArr - Optional array to bypass prompts
145
* @returns Promise resolving to user answers
146
*/
147
runPrompts(bypassArr?: string[]): Promise<any>;
148
```
149
150
[Generator Management](./generator-api.md)
151
152
### Template System
153
154
Handlebars templating with built-in helpers, custom helpers, and partials for flexible file generation.
155
156
```javascript { .api }
157
/**
158
* Register a custom Handlebars helper
159
* @param name - Helper name for use in templates
160
* @param fn - Helper function
161
*/
162
setHelper(name: string, fn: HelperFunction): void;
163
164
/**
165
* Register a Handlebars partial
166
* @param name - Partial name for use in templates
167
* @param str - Partial template string
168
*/
169
setPartial(name: string, str: string): void;
170
171
/**
172
* Render a Handlebars template string with data
173
* @param template - Handlebars template string
174
* @param data - Data object for template rendering
175
* @returns Rendered string
176
*/
177
renderString(template: string, data: any): string;
178
```
179
180
[Template System](./template-system.md)
181
182
### Action System
183
184
Built-in file operations (add, addMany, modify, append) and support for custom actions.
185
186
```javascript { .api }
187
/**
188
* Register a custom action type
189
* @param name - Action type name
190
* @param fn - Action function
191
*/
192
setActionType(name: string, fn: CustomActionFunction): void;
193
194
// Built-in action configuration interfaces
195
interface AddActionConfig extends ActionConfig {
196
type: "add";
197
path: string;
198
skipIfExists?: boolean;
199
} & TemplateStrOrFile;
200
201
interface ModifyActionConfig extends ActionConfig {
202
type: "modify";
203
path: string;
204
pattern: string | RegExp;
205
} & TemplateStrOrFile;
206
```
207
208
[Action System](./action-system.md)
209
210
### Console Output and User Interface
211
212
User interface functions for displaying help, selecting generators, and creating initial plopfiles.
213
214
```javascript { .api }
215
/**
216
* Display generator selection list to user
217
* @param plopList - Array of available generators
218
* @param message - Optional custom selection message
219
* @returns Promise resolving to selected generator name
220
*/
221
async function chooseOptionFromList(plopList, message);
222
223
/**
224
* Display help screen with usage information
225
*/
226
function displayHelpScreen();
227
228
/**
229
* Create initial plopfile.js or plopfile.ts
230
* @param force - Overwrite existing plopfile if present
231
* @param useTypescript - Generate TypeScript plopfile
232
*/
233
function createInitPlopfile(force, useTypescript);
234
```
235
236
[Console Interface](./console.md)
237
238
## Types
239
240
```javascript { .api }
241
// Core configuration types
242
interface PlopCfg {
243
force?: boolean; // Force overwrite existing files
244
destBasePath?: string; // Base path for file operations
245
}
246
247
interface PlopGeneratorConfig {
248
description: string; // Human-readable description
249
prompts: Prompts; // Inquirer prompts or function
250
actions: Actions; // Actions to perform or function
251
}
252
253
// Generator and API interfaces
254
interface NodePlopAPI {
255
setGenerator(name: string, config: Partial<PlopGeneratorConfig>): PlopGenerator;
256
getGenerator(name: string): PlopGenerator;
257
getGeneratorList(): { name: string; description: string }[];
258
setHelper(name: string, fn: HelperFunction): void;
259
setPartial(name: string, str: string): void;
260
setActionType(name: string, fn: CustomActionFunction): void;
261
renderString(template: string, data: any): string;
262
}
263
264
interface PlopGenerator extends PlopGeneratorConfig {
265
runPrompts(bypassArr?: string[]): Promise<any>;
266
runActions(answers: Answers, hooks?: PlopActionHooks): Promise<{
267
changes: PlopActionHooksChanges[];
268
failures: PlopActionHooksFailures[];
269
}>;
270
}
271
272
// Action configuration types
273
interface ActionConfig {
274
type: string; // Action type name
275
force?: boolean; // Force overwrite
276
data?: object; // Additional template data
277
abortOnFail?: boolean; // Abort on action failure
278
skip?: Function; // Conditional skip function
279
}
280
281
interface AddActionConfig extends ActionConfig {
282
type: "add";
283
path: string;
284
skipIfExists?: boolean;
285
} & TemplateStrOrFile;
286
287
interface AddManyActionConfig extends ActionConfig {
288
type: "addMany";
289
destination: string;
290
base: string;
291
templateFiles: string | string[];
292
stripExtensions?: string[];
293
globOptions?: GlobOptions;
294
verbose?: boolean;
295
}
296
297
interface ModifyActionConfig extends ActionConfig {
298
type: "modify";
299
path: string;
300
pattern: string | RegExp;
301
} & TemplateStrOrFile;
302
303
interface AppendActionConfig extends ActionConfig {
304
type: "append";
305
path: string;
306
pattern: string | RegExp;
307
unique?: boolean;
308
separator?: string;
309
} & TemplateStrOrFile;
310
311
// Template and prompt types
312
interface TemplateStrOrFile {
313
template?: string; // Inline template string
314
templateFile?: string; // Path to template file
315
}
316
317
type Prompts = DynamicPromptsFunction | PromptQuestion[];
318
type Actions = DynamicActionsFunction | ActionType[];
319
type ActionType = AddActionConfig | AddManyActionConfig | ModifyActionConfig | AppendActionConfig | CustomActionConfig<string>;
320
321
type DynamicPromptsFunction = (inquirer: Inquirer) => Promise<Answers>;
322
type DynamicActionsFunction = (data?: Answers) => ActionType[];
323
type CustomActionFunction = (
324
answers: Answers,
325
config: CustomActionConfig<string>,
326
plopfileApi: NodePlopAPI,
327
) => Promise<string> | string;
328
329
// Hook system types
330
interface PlopActionHooks {
331
onComment?: (msg: string) => void;
332
onSuccess?: (change: PlopActionHooksChanges) => void;
333
onFailure?: (failure: PlopActionHooksFailures) => void;
334
}
335
336
interface PlopActionHooksChanges {
337
type: string;
338
path: string;
339
}
340
341
interface PlopActionHooksFailures {
342
type: string;
343
path: string;
344
error: string;
345
message: string;
346
}
347
348
// CLI and environment types
349
interface EnvironmentOptions {
350
cwd?: string;
351
preload?: string[];
352
configPath?: string;
353
completion?: any;
354
}
355
356
interface GeneratorInfo {
357
name: string;
358
description?: string;
359
}
360
361
// External library types
362
interface Liftoff {
363
prepare(options: PrepareOptions, callback: (env: LiftoffEnvironment) => void): void;
364
execute(env: LiftoffEnvironment, run: Function): any;
365
}
366
367
interface PrepareOptions {
368
cwd?: string;
369
preload?: string[];
370
configPath?: string;
371
completion?: any;
372
}
373
374
interface LiftoffEnvironment {
375
configPath: string;
376
cwd: string;
377
require: Function;
378
configName: string;
379
configBase: string;
380
configNameSearch: string[];
381
modulePackage: object;
382
modules: object;
383
}
384
385
interface Ora {
386
start(): Ora;
387
stop(): Ora;
388
succeed(text?: string): Ora;
389
fail(text?: string): Ora;
390
info(text?: string): Ora;
391
}
392
```