UNPKG

17.8 kBMarkdownView Raw
1# composer [![NPM version](https://img.shields.io/npm/v/composer.svg?style=flat)](https://www.npmjs.com/package/composer) [![NPM monthly downloads](https://img.shields.io/npm/dm/composer.svg?style=flat)](https://npmjs.org/package/composer) [![NPM total downloads](https://img.shields.io/npm/dt/composer.svg?style=flat)](https://npmjs.org/package/composer) [![Linux Build Status](https://img.shields.io/travis/doowb/composer.svg?style=flat&label=Travis)](https://travis-ci.org/doowb/composer) [![Windows Build Status](https://img.shields.io/appveyor/ci/doowb/composer.svg?style=flat&label=AppVeyor)](https://ci.appveyor.com/project/doowb/composer)
2
3> Run and compose async tasks. Easily define groups of tasks to run in series or parallel.
4
5Please consider following this project's author, [Brian Woodward](https://github.com/doowb), and consider starring the project to show your :heart: and support.
6
7- [Install](#install)
8- [Usage](#usage)
9- [API](#api)
10 * [Tasks](#tasks)
11 * [Generators](#generators)
12- [Events](#events)
13 * [task](#task)
14 * [task-pending](#task-pending)
15 * [task-preparing](#task-preparing)
16- [Release history](#release-history)
17- [About](#about)
18
19_(TOC generated by [verb](https://github.com/verbose/verb) using [markdown-toc](https://github.com/jonschlinkert/markdown-toc))_
20
21## Install
22
23Install with [npm](https://www.npmjs.com/):
24
25```sh
26$ npm install --save composer
27```
28
29## Usage
30
31```js
32// Create an instance of `Composer`
33const Composer = require('composer');
34const composer = new Composer();
35
36// Define tasks with the .task() method
37composer.task('foo', callback => {
38 callback(); // do stuff
39});
40composer.task('bar', callback => {
41 callback(); // do stuff
42});
43
44composer.task('baz', ['foo'. 'bar']);
45
46// Run tasks with the .build() method
47composer.build('baz')
48 .then(() => console.log('done!'))
49 .catch(console.error);
50```
51
52## API
53
54### [.factory](lib/tasks.js#L27)
55
56Factory for creating a custom `Tasks` class that extends the given `Emitter`. Or, simply call the factory function to use the built-in emitter.
57
58**Params**
59
60* `Emitter` **{function}**: Event emitter.
61* `returns` **{Class}**: Returns a custom `Tasks` class.
62
63**Example**
64
65```js
66// custom emitter
67const Emitter = require('events');
68const Tasks = require('composer/lib/tasks')(Emitter);
69// built-in emitter
70const Tasks = require('composer/lib/tasks')();
71const composer = new Tasks();
72```
73
74### [Tasks](lib/tasks.js#L42)
75
76Create an instance of `Tasks` with the given `options`.
77
78**Params**
79
80* `options` **{object}**
81
82**Example**
83
84```js
85const Tasks = require('composer').Tasks;
86const composer = new Tasks();
87```
88
89### [.task](lib/tasks.js#L86)
90
91Define a task. Tasks run asynchronously, either in series (by default) or parallel (when `options.parallel` is true). In order for the build to determine when a task is complete, _one of the following_ things must happen: 1) the callback must be called, 2) a promise must be returned, or 3) a stream must be returned. Inside tasks, the "this" object is a composer Task instance created for each task with useful properties like the task name, options and timing information, which can be useful for logging, etc.
92
93**Params**
94
95* `name` **{String}**: The task name.
96* `deps` **{Object|Array|String|Function}**: Any of the following: task dependencies, callback(s), or options object, defined in any order.
97* `callback` **{Function}**: (optional) If the last argument is a function, it will be called after all of the task's dependencies have been run.
98* `returns` **{undefined}**
99
100**Example**
101
102```js
103// 1. callback
104app.task('default', cb => {
105 // do stuff
106 cb();
107});
108// 2. promise
109app.task('default', () => {
110 return Promise.resolve(null);
111});
112// 3. stream (using vinyl-fs or your stream of choice)
113app.task('default', function() {
114 return vfs.src('foo/*.js');
115});
116```
117
118### [.build](lib/tasks.js#L209)
119
120Run one or more tasks.
121
122**Params**
123
124* `tasks` **{object|array|string|function}**: One or more tasks to run, options, or callback function. If no tasks are defined, the default task is automatically run.
125* `callback` **{function}**: (optional)
126* `returns` **{undefined}**
127
128**Example**
129
130```js
131const build = app.series(['foo', 'bar', 'baz']);
132// promise
133build().then(console.log).catch(console.error);
134// or callback
135build(function() {
136 if (err) return console.error(err);
137});
138```
139
140### [.series](lib/tasks.js#L251)
141
142Compose a function to run the given tasks in series.
143
144**Params**
145
146* `tasks` **{object|array|string|function}**: Tasks to run, options, or callback function. If no tasks are defined, the `default` task is automatically run, if one exists.
147* `callback` **{function}**: (optional)
148* `returns` **{promise|undefined}**: Returns a promise if no callback is passed.
149
150**Example**
151
152```js
153const build = app.series(['foo', 'bar', 'baz']);
154// promise
155build().then(console.log).catch(console.error);
156// or callback
157build(function() {
158 if (err) return console.error(err);
159});
160```
161
162### [.parallel](lib/tasks.js#L304)
163
164Compose a function to run the given tasks in parallel.
165
166**Params**
167
168* `tasks` **{object|array|string|function}**: Tasks to run, options, or callback function. If no tasks are defined, the `default` task is automatically run, if one exists.
169* `callback` **{function}**: (optional)
170* `returns` **{promise|undefined}**: Returns a promise if no callback is passed.
171
172**Example**
173
174```js
175// call the returned function to start the build
176const build = app.parallel(['foo', 'bar', 'baz']);
177// promise
178build().then(console.log).catch(console.error);
179// callback
180build(function() {
181 if (err) return console.error(err);
182});
183// example task usage
184app.task('default', build);
185```
186
187### [.create](lib/tasks.js#L388)
188
189Static method for creating a custom Tasks class with the given `Emitter.
190
191**Params**
192
193* `Emitter` **{Function}**
194* `returns` **{Class}**: Returns the custom class.
195
196### [.create](lib/generator.js#L30)
197
198Static factory method for creating a custom `Composer` class that extends the given `Emitter`.
199
200**Params**
201
202* `Emitter` **{Function}**: Event emitter.
203* `returns` **{Class}**: Returns a custom `Composer` class.
204
205**Example**
206
207```js
208// Composer extends a basic event emitter by default
209const Composer = require('composer');
210const composer = new Composer();
211
212// Create a custom Composer class with your even emitter of choice
213const Emitter = require('some-emitter');
214const CustomComposer = Composer.create(Emitter);
215const composer = new CustomComposer();
216```
217
218**Params**
219
220* `name` **{String}**
221* `options` **{Object}**
222* `returns` **{Object}**: Returns an instance of Composer.
223
224**Example**
225
226```js
227const composer = new Composer();
228```
229
230Create a wrapped generator function with the given `name`, `config`, and `fn`.
231
232**Params**
233
234* `name` **{String}**
235* `config` **{Object}**: (optional)
236* `fn` **{Function}**
237* `returns` **{Function}**
238
239Returns true if the given value is a Composer generator object.
240
241**Params**
242
243* `val` **{Object}**
244* `returns` **{Boolean}**
245
246### [.register](lib/generator.js#L167)
247
248Alias to `.setGenerator`.
249
250**Params**
251
252* `name` **{String}**: The generator's name
253* `options` **{Object|Function|String}**: or generator
254* `generator` **{Object|Function|String}**: Generator function, instance or filepath.
255* `returns` **{Object}**: Returns the generator instance.
256
257**Example**
258
259```js
260app.register('foo', function(app, base) {
261 // "app" is a private instance created for the generator
262 // "base" is a shared instance
263});
264```
265
266### [.generator](lib/generator.js#L190)
267
268Get and invoke generator `name`, or register generator `name` with the given `val` and `options`, then invoke and return the generator instance. This method differs from `.register`, which lazily invokes generator functions when `.generate` is called.
269
270**Params**
271
272* `name` **{String}**
273* `fn` **{Function|Object}**: Generator function, instance or filepath.
274* `returns` **{Object}**: Returns the generator instance or undefined if not resolved.
275
276**Example**
277
278```js
279app.generator('foo', function(app, options) {
280 // "app" - private instance created for generator "foo"
281 // "options" - options passed to the generator
282});
283```
284
285### [.setGenerator](lib/generator.js#L222)
286
287Store a generator by file path or instance with the given `name` and `options`.
288
289**Params**
290
291* `name` **{String}**: The generator's name
292* `options` **{Object|Function|String}**: or generator
293* `generator` **{Object|Function|String}**: Generator function, instance or filepath.
294* `returns` **{Object}**: Returns the generator instance.
295
296**Example**
297
298```js
299app.setGenerator('foo', function(app, options) {
300 // "app" - new instance of Generator created for generator "foo"
301 // "options" - options passed to the generator
302});
303```
304
305### [.getGenerator](lib/generator.js#L247)
306
307Get generator `name` from `app.generators`, same as [findGenerator], but also invokes the returned generator with the current instance. Dot-notation may be used for getting sub-generators.
308
309**Params**
310
311* `name` **{String}**: Generator name.
312* `returns` **{Object|undefined}**: Returns the generator instance or undefined.
313
314**Example**
315
316```js
317const foo = app.getGenerator('foo');
318
319// get a sub-generator
320const baz = app.getGenerator('foo.bar.baz');
321```
322
323### [.findGenerator](lib/generator.js#L280)
324
325Find generator `name`, by first searching the cache, then searching the cache of the `base` generator. Use this to get a generator without invoking it.
326
327**Params**
328
329* `name` **{String}**
330* `options` **{Function}**: Optionally supply a rename function on `options.toAlias`
331* `returns` **{Object|undefined}**: Returns the generator instance if found, or undefined.
332
333**Example**
334
335```js
336// search by "alias"
337const foo = app.findGenerator('foo');
338
339// search by "full name"
340const foo = app.findGenerator('generate-foo');
341```
342
343**Params**
344
345* `name` **{String}**
346* `returns` **{Boolean}**
347
348**Example**
349
350```js
351console.log(app.hasGenerator('foo'));
352console.log(app.hasGenerator('foo.bar'));
353```
354
355### [.generate](lib/generator.js#L362)
356
357Run one or more tasks or sub-generators and returns a promise.
358
359**Params**
360
361* `name` **{String}**
362* `tasks` **{String|Array}**
363* `returns` **{Promise}**
364
365**Events**
366
367* `emits`: `generate` with the generator `name` and the array of `tasks` that are queued to run.
368
369**Example**
370
371```js
372// run tasks `bar` and `baz` on generator `foo`
373app.generate('foo', ['bar', 'baz']);
374
375// or use shorthand
376app.generate('foo:bar,baz');
377
378// run the `default` task on generator `foo`
379app.generate('foo');
380
381// run the `default` task on the `default` generator, if defined
382app.generate();
383```
384
385### [.toAlias](lib/generator.js#L413)
386
387Create a generator alias from the given `name`. By default, `generate-` is stripped from beginning of the generator name.
388
389**Params**
390
391* `name` **{String}**
392* `options` **{Object}**
393* `returns` **{String}**: Returns the alias.
394
395**Example**
396
397```js
398// customize the alias
399const app = new Generate({ toAlias: require('camel-case') });
400```
401
402### [.isGenerators](lib/generator.js#L434)
403
404Returns true if every name in the given array is a registered generator.
405
406**Params**
407
408* `names` **{Array}**
409* `returns` **{Boolean}**
410
411### [.formatError](lib/generator.js#L446)
412
413Format task and generator errors.
414
415**Params**
416
417* `name` **{String}**
418* `returns` **{Error}**
419
420### [.disableInspect](lib/generator.js#L466)
421
422Disable inspect. Returns a function to re-enable inspect. Useful for debugging.
423
424### [.base](lib/generator.js#L504)
425
426Get the first ancestor instance of Composer. Only works if `generator.parent` is
427defined on child instances.
428
429### [.name](lib/generator.js#L517)
430
431Get or set the generator name.
432
433**Params**
434
435* **{String}**
436
437* `returns` **{String}**
438
439### [.alias](lib/generator.js#L534)
440
441Get or set the generator `alias`. By default, the generator alias is created
442by passing the generator name to the [.toAlias](#toAlias) method.
443
444**Params**
445
446* **{String}**
447
448* `returns` **{String}**
449
450### [.namespace](lib/generator.js#L551)
451
452Get the generator namespace. The namespace is created by joining the generator's `alias`
453to the alias of each ancestor generator.
454
455**Params**
456
457* **{String}**
458
459* `returns` **{String}**
460
461### [.depth](lib/generator.js#L564)
462
463Get the depth of a generator - useful for debugging. The root generator
464has a depth of `0`, sub-generators add `1` for each level of nesting.
465
466* `returns` **{Number}**
467
468### [Composer#parse](lib/generator.js#L577)
469
470Static method that returns a function for parsing task arguments.
471
472**Params**
473
474* `register` **{Function}**: Function that receives a name of a task or generator that cannot be found by the parse function. This allows the `register` function to dynamically register tasks or generators.
475* `returns` **{Function}**: Returns a function for parsing task args.
476
477### [Composer#isGenerator](lib/generator.js#L590)
478
479Static method that returns true if the given `val` is an instance of Generate.
480
481**Params**
482
483* `val` **{Object}**
484* `returns` **{Boolean}**
485
486### [Composer#create](lib/generator.js#L603)
487
488Static method for creating a custom Composer class with the given `Emitter.
489
490**Params**
491
492* `Emitter` **{Function}**
493* `returns` **{Class}**: Returns the custom class.
494
495### [Composer#Tasks](lib/generator.js#L617)
496
497Static getter for getting the Tasks class with the same `Emitter` class as Composer.
498
499**Params**
500
501* `Emitter` **{Function}**
502* `returns` **{Class}**: Returns the Tasks class.
503
504### [Composer#Task](lib/generator.js#L633)
505
506Static getter for getting the `Task` class.
507
508**Example**
509
510```js
511const { Task } = require('composer');
512```
513
514## Events
515
516### task
517
518```js
519app.on('task', function(task) {
520 switch (task.status) {
521 case 'starting':
522 // Task is running
523 break;
524 case 'finished':
525 // Task is finished running
526 break;
527 }
528});
529```
530
531### task-pending
532
533Emitted after a task is registered.
534
535### task-preparing
536
537Emitted when a task is preparing to run, right before it's called. You can use this event to dynamically skip tasks by updating `task.skip` to `true` or a function.
538
539## Release history
540
541See the [changelog](./CHANGELOG.md).
542
543## About
544
545<details>
546<summary><strong>Contributing</strong></summary>
547
548Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).
549
550</details>
551
552<details>
553<summary><strong>Running Tests</strong></summary>
554
555Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:
556
557```sh
558$ npm install && npm test
559```
560
561</details>
562
563<details>
564<summary><strong>Building docs</strong></summary>
565
566_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_
567
568To generate the readme, run the following command:
569
570```sh
571$ npm install -g verbose/verb#dev verb-generate-readme && verb
572```
573
574</details>
575
576### Related projects
577
578You might also be interested in these projects:
579
580* [assemble](https://www.npmjs.com/package/assemble): Get the rocks out of your socks! Assemble makes you fast at creating web projects… [more](https://github.com/assemble/assemble) | [homepage](https://github.com/assemble/assemble "Get the rocks out of your socks! Assemble makes you fast at creating web projects. Assemble is used by thousands of projects for rapid prototyping, creating themes, scaffolds, boilerplates, e-books, UI components, API documentation, blogs, building websit")
581* [enquirer](https://www.npmjs.com/package/enquirer): Stylish, intuitive and user-friendly prompt system. Fast and lightweight enough for small projects, powerful and… [more](https://github.com/enquirer/enquirer) | [homepage](https://github.com/enquirer/enquirer "Stylish, intuitive and user-friendly prompt system. Fast and lightweight enough for small projects, powerful and extensible enough for the most advanced use cases.")
582* [generate](https://www.npmjs.com/package/generate): Command line tool and developer framework for scaffolding out new GitHub projects. Generate offers the… [more](https://github.com/generate/generate) | [homepage](https://github.com/generate/generate "Command line tool and developer framework for scaffolding out new GitHub projects. Generate offers the robustness and configurability of Yeoman, the expressiveness and simplicity of Slush, and more powerful flow control and composability than either.")
583* [update](https://www.npmjs.com/package/update): Be scalable! Update is a new, open source developer framework and CLI for automating updates… [more](https://github.com/update/update) | [homepage](https://github.com/update/update "Be scalable! Update is a new, open source developer framework and CLI for automating updates of any kind in code projects.")
584* [verb](https://www.npmjs.com/package/verb): Documentation generator for GitHub projects. Verb is extremely powerful, easy to use, and is used… [more](https://github.com/verbose/verb) | [homepage](https://github.com/verbose/verb "Documentation generator for GitHub projects. Verb is extremely powerful, easy to use, and is used on hundreds of projects of all sizes to generate everything from API docs to readmes.")
585
586### Contributors
587
588| **Commits** | **Contributor** |
589| --- | --- |
590| 227 | [doowb](https://github.com/doowb) |
591| 72 | [jonschlinkert](https://github.com/jonschlinkert) |
592
593### Author
594
595**Brian Woodward**
596
597* [GitHub Profile](https://github.com/doowb)
598* [Twitter Profile](https://twitter.com/doowb)
599* [LinkedIn Profile](https://linkedin.com/in/woodwardbrian)
600
601### License
602
603Copyright © 2018, [Brian Woodward](https://github.com/doowb).
604Released under the [MIT License](LICENSE).
605
606***
607
608_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on November 11, 2018._
\No newline at end of file