UNPKG

17.7 kBMarkdownView Raw
1# Concurrently
2
3[![Build Status](https://github.com/open-cli-tools/concurrently/workflows/Tests/badge.svg)](https://github.com/open-cli-tools/concurrently/actions?workflow=Tests)
4[![Coverage Status](https://coveralls.io/repos/github/open-cli-tools/concurrently/badge.svg?branch=master)](https://coveralls.io/github/open-cli-tools/concurrently?branch=master)
5
6[![NPM Badge](https://nodei.co/npm/concurrently.png?downloads=true)](https://www.npmjs.com/package/concurrently)
7
8Run multiple commands concurrently.
9Like `npm run watch-js & npm run watch-less` but better.
10
11![](docs/demo.gif)
12
13**Table of contents**
14- [Concurrently](#concurrently)
15 - [Why](#why)
16 - [Install](#install)
17 - [Usage](#usage)
18 - [API](#api)
19 - [`concurrently(commands[, options])`](#concurrentlycommands-options)
20 - [`Command`](#command)
21 - [`CloseEvent`](#closeevent)
22 - [FAQ](#faq)
23
24## Why
25
26I like [task automation with npm](https://github.com/substack/blog/blob/master/npm_run.markdown)
27but the usual way to run multiple commands concurrently is
28`npm run watch-js & npm run watch-css`. That's fine but it's hard to keep
29on track of different outputs. Also if one process fails, others still keep running
30and you won't even notice the difference.
31
32Another option would be to just run all commands in separate terminals. I got
33tired of opening terminals and made **concurrently**.
34
35**Features:**
36
37* Cross platform (including Windows)
38* Output is easy to follow with prefixes
39* With `--kill-others` switch, all commands are killed if one dies
40* Spawns commands with [spawn-command](https://github.com/mmalecki/spawn-command)
41
42## Install
43
44The tool is written in Node.js, but you can use it to run **any** commands.
45
46```bash
47npm install -g concurrently
48```
49
50or if you are using it from npm scripts:
51
52```bash
53npm install concurrently --save
54```
55
56## Usage
57
58Remember to surround separate commands with quotes:
59```bash
60concurrently "command1 arg" "command2 arg"
61```
62
63Otherwise **concurrently** would try to run 4 separate commands:
64`command1`, `arg`, `command2`, `arg`.
65
66In package.json, escape quotes:
67
68```bash
69"start": "concurrently \"command1 arg\" \"command2 arg\""
70```
71
72NPM run commands can be shortened:
73
74```bash
75concurrently "npm:watch-js" "npm:watch-css" "npm:watch-node"
76
77# Equivalent to:
78concurrently -n watch-js,watch-css,watch-node "npm run watch-js" "npm run watch-css" "npm run watch-node"
79```
80
81NPM shortened commands also support wildcards. Given the following scripts in
82package.json:
83
84```javascript
85{
86 //...
87 "scripts": {
88 // ...
89 "watch-js": "...",
90 "watch-css": "...",
91 "watch-node": "...",
92 // ...
93 },
94 // ...
95}
96```
97
98```bash
99concurrently "npm:watch-*"
100
101# Equivalent to:
102concurrently -n js,css,node "npm run watch-js" "npm run watch-css" "npm run watch-node"
103
104# Any name provided for the wildcard command will be used as a prefix to the wildcard
105# part of the script name:
106concurrently -n w: npm:watch-*
107
108# Equivalent to:
109concurrently -n w:js,w:css,w:node "npm run watch-js" "npm run watch-css" "npm run watch-node"
110```
111
112Exclusion is also supported. Given the following scripts in package.json:
113```javascript
114{
115 // ...
116 "scripts": {
117 "lint:js": "...",
118 "lint:ts": "...",
119 "lint:fix:js": "...",
120 "lint:fix:ts": "...",
121 // ...
122 }
123 // ...
124}
125```
126```bash
127# Running only lint:js and lint:ts
128# with lint:fix:js and lint:fix:ts excluded
129concurrently "npm:lint:*(!fix)"
130```
131
132Good frontend one-liner example [here](https://github.com/kimmobrunfeldt/dont-copy-paste-this-frontend-template/blob/5cd2bde719654941bdfc0a42c6f1b8e69ae79980/package.json#L9).
133
134Help:
135
136```
137concurrently [options] <command ...>
138
139General
140 -m, --max-processes How many processes should run at once.
141 New processes only spawn after all restart tries
142 of a process. [number]
143 -n, --names List of custom names to be used in prefix
144 template.
145 Example names: "main,browser,server" [string]
146 --name-separator The character to split <names> on. Example usage:
147 concurrently -n "styles|scripts|server"
148 --name-separator "|" [default: ","]
149 -s, --success Which command(s) must exit with code 0 in order
150 for concurrently exit with code 0 too. Options
151 are:
152 - "first" for the first command to exit;
153 - "last" for the last command to exit;
154 - "all" for all commands;
155 - "command-{name}"/"command-{index}" for the
156 commands with that name or index;
157 - "!command-{name}"/"!command-{index}" for all
158 commands but the ones with that name or index.
159 [default: "all"]
160 -r, --raw Output only raw output of processes, disables
161 prettifying and concurrently coloring. [boolean]
162 --no-color Disables colors from logging [boolean]
163 --hide Comma-separated list of processes to hide the
164 output.
165 The processes can be identified by their name or
166 index. [string] [default: ""]
167 -g, --group Order the output as if the commands were run
168 sequentially. [boolean]
169 --timings Show timing information for all processes.
170 [boolean] [default: false]
171 -P, --passthrough-arguments Passthrough additional arguments to commands
172 (accessible via placeholders) instead of treating
173 them as commands. [boolean] [default: false]
174
175Prefix styling
176 -p, --prefix Prefix used in logging for each process.
177 Possible values: index, pid, time, command, name,
178 none, or a template. Example template: "{time}-{pid}"
179 [string] [default: index or name (when --names is set)]
180 -c, --prefix-colors Comma-separated list of chalk colors to use on
181 prefixes. If there are more commands than colors, the
182 last color will be repeated.
183 - Available modifiers: reset, bold, dim, italic,
184 underline, inverse, hidden, strikethrough
185 - Available colors: black, red, green, yellow, blue,
186 magenta, cyan, white, gray
187 or any hex values for colors, eg #23de43
188 - Available background colors: bgBlack, bgRed,
189 bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite
190 See https://www.npmjs.com/package/chalk for more
191 information. [string] [default: "reset"]
192 -l, --prefix-length Limit how many characters of the command is displayed
193 in prefix. The option can be used to shorten the
194 prefix when it is set to "command"
195 [number] [default: 10]
196 -t, --timestamp-format Specify the timestamp in moment/date-fns format.
197 [string] [default: "yyyy-MM-dd HH:mm:ss.SSS"]
198
199Input handling
200 -i, --handle-input Whether input should be forwarded to the child
201 processes. See examples for more information.
202 [boolean]
203 --default-input-target Identifier for child process to which input on
204 stdin should be sent if not specified at start of
205 input.
206 Can be either the index or the name of the
207 process. [default: 0]
208
209Killing other processes
210 -k, --kill-others Kill other processes if one exits or dies.[boolean]
211 --kill-others-on-fail Kill other processes if one exits with non zero
212 status code. [boolean]
213
214Restarting
215 --restart-tries How many times a process that died should restart.
216 Negative numbers will make the process restart forever.
217 [number] [default: 0]
218 --restart-after Delay time to respawn the process, in milliseconds.
219 [number] [default: 0]
220
221Options:
222 -h, --help Show help [boolean]
223 -v, -V, --version Show version number [boolean]
224
225
226Examples:
227
228 - Output nothing more than stdout+stderr of child processes
229
230 $ concurrently --raw "npm run watch-less" "npm run watch-js"
231
232 - Normal output but without colors e.g. when logging to file
233
234 $ concurrently --no-color "grunt watch" "http-server" > log
235
236 - Custom prefix
237
238 $ concurrently --prefix "{time}-{pid}" "npm run watch" "http-server"
239
240 - Custom names and colored prefixes
241
242 $ concurrently --names "HTTP,WATCH" -c "bgBlue.bold,bgMagenta.bold"
243 "http-server" "npm run watch"
244
245 - Configuring via environment variables with CONCURRENTLY_ prefix
246
247 $ CONCURRENTLY_RAW=true CONCURRENTLY_KILL_OTHERS=true concurrently "echo
248 hello" "echo world"
249
250 - Send input to default
251
252 $ concurrently --handle-input "nodemon" "npm run watch-js"
253 rs # Sends rs command to nodemon process
254
255 - Send input to specific child identified by index
256
257 $ concurrently --handle-input "npm run watch-js" nodemon
258 1:rs
259
260 - Send input to specific child identified by name
261
262 $ concurrently --handle-input -n js,srv "npm run watch-js" nodemon
263 srv:rs
264
265 - Shortened NPM run commands
266
267 $ concurrently npm:watch-node npm:watch-js npm:watch-css
268
269 - Shortened NPM run command with wildcard (make sure to wrap it in quotes!)
270
271 $ concurrently "npm:watch-*"
272
273 - Exclude patterns so that between "lint:js" and "lint:fix:js", only "lint:js"
274 is ran
275
276 $ concurrently "npm:*(!fix)"
277
278 - Passthrough some additional arguments via '{<number>}' placeholder
279
280 $ concurrently -P "echo {1}" -- foo
281
282 - Passthrough all additional arguments via '{@}' placeholder
283
284 $ concurrently -P "npm:dev-* -- {@}" -- --watch --noEmit
285
286 - Passthrough all additional arguments combined via '{*}' placeholder
287
288 $ concurrently -P "npm:dev-* -- {*}" -- --watch --noEmit
289
290For more details, visit https://github.com/open-cli-tools/concurrently
291```
292
293## API
294concurrently can be used programmatically by using the API documented below:
295
296### `concurrently(commands[, options])`
297
298- `commands`: an array of either strings (containing the commands to run) or objects
299 with the shape `{ command, name, prefixColor, env, cwd }`.
300
301- `options` (optional): an object containing any of the below:
302 - `cwd`: the working directory to be used by all commands. Can be overriden per command.
303 Default: `process.cwd()`.
304 - `defaultInputTarget`: the default input target when reading from `inputStream`.
305 Default: `0`.
306 - `handleInput`: when `true`, reads input from `process.stdin`.
307 - `inputStream`: a [`Readable` stream](https://nodejs.org/dist/latest-v10.x/docs/api/stream.html#stream_readable_streams)
308 to read the input from. Should only be used in the rare instance you would like to stream anything other than `process.stdin`. Overrides `handleInput`.
309 - `pauseInputStreamOnFinish`: by default, pauses the input stream (`process.stdin` when `handleInput` is enabled, or `inputStream` if provided) when all of the processes have finished. If you need to read from the input stream after `concurrently` has finished, set this to `false`. ([#252](https://github.com/kimmobrunfeldt/concurrently/issues/252)).
310 - `killOthers`: an array of exitting conditions that will cause a process to kill others.
311 Can contain any of `success` or `failure`.
312 - `maxProcesses`: how many processes should run at once.
313 - `outputStream`: a [`Writable` stream](https://nodejs.org/dist/latest-v10.x/docs/api/stream.html#stream_writable_streams)
314 to write logs to. Default: `process.stdout`.
315 - `prefix`: the prefix type to use when logging processes output.
316 Possible values: `index`, `pid`, `time`, `command`, `name`, `none`, or a template (eg `[{time} process: {pid}]`).
317 Default: the name of the process, or its index if no name is set.
318 - `prefixColors`: a list of colors as supported by [chalk](https://www.npmjs.com/package/chalk).
319 If concurrently would run more commands than there are colors, the last color is repeated.
320 Prefix colors specified per-command take precedence over this list.
321 - `prefixLength`: how many characters to show when prefixing with `command`. Default: `10`
322 - `raw`: whether raw mode should be used, meaning strictly process output will
323 be logged, without any prefixes, colouring or extra stuff.
324 - `successCondition`: the condition to consider the run was successful.
325 If `first`, only the first process to exit will make up the success of the run; if `last`, the last process that exits will determine whether the run succeeds.
326 Anything else means all processes should exit successfully.
327 - `restartTries`: how many attempts to restart a process that dies will be made. Default: `0`.
328 - `restartDelay`: how many milliseconds to wait between process restarts. Default: `0`.
329 - `timestampFormat`: a [date-fns format](https://date-fns.org/v2.0.1/docs/format)
330 to use when prefixing with `time`. Default: `yyyy-MM-dd HH:mm:ss.ZZZ`
331 - `additionalArguments`: list of additional arguments passed that will get replaced in each command. If not defined, no argument replacing will happen.
332
333> **Returns:** an object in the shape `{ result, commands }`.
334> - `result`: a `Promise` that resolves if the run was successful (according to `successCondition` option),
335> or rejects, containing an array of [`CloseEvent`](#CloseEvent), in the order that the commands terminated.
336> - `commands`: an array of all spawned [`Command`s](#Command).
337
338Example:
339
340```js
341const concurrently = require('concurrently');
342const { result } = concurrently([
343 'npm:watch-*',
344 { command: 'nodemon', name: 'server' },
345 { command: 'deploy', name: 'deploy', env: { PUBLIC_KEY: '...' } },
346 { command: 'watch', name: 'watch', cwd: path.resolve(__dirname, 'scripts/watchers')}
347], {
348 prefix: 'name',
349 killOthers: ['failure', 'success'],
350 restartTries: 3,
351 cwd: path.resolve(__dirname, 'scripts'),
352});
353result.then(success, failure);
354```
355
356### `Command`
357An object that contains all information about a spawned command, and ways to interact with it.<br>
358It has the following properties:
359
360- `index`: the index of the command among all commands spawned.
361- `command`: the command line of the command.
362- `name`: the name of the command; defaults to an empty string.
363- `cwd`: the current working directory of the command.
364- `env`: an object with all the environment variables that the command will be spawned with.
365- `killed`: whether the command has been killed.
366- `exited`: whether the command exited yet.
367- `pid`: the command's process ID.
368- `stdin`: a Writable stream to the command's `stdin`.
369- `stdout`: an RxJS observable to the command's `stdout`.
370- `stderr`: an RxJS observable to the command's `stderr`.
371- `error`: an RxJS observable to the command's error events (e.g. when it fails to spawn).
372- `timer`: an RxJS observable to the command's timing events (e.g. starting, stopping).
373- `close`: an RxJS observable to the command's close events.
374 See [`CloseEvent`](#CloseEvent) for more information.
375- `start()`: starts the command, setting up all
376- `kill([signal])`: kills the command, optionally specifying a signal (e.g. `SIGTERM`, `SIGKILL`, etc).
377
378### `CloseEvent`
379An object with information about a command's closing event.<br>
380It contains the following properties:
381
382- `command`: a stripped down version of [`Command`](#command), including only `name`, `command`, `env` and `cwd` properties.
383- `index`: the index of the command among all commands spawned.
384- `killed`: whether the command exited because it was killed.
385- `exitCode`: the exit code of the command's process, or the signal which it was killed with.
386- `timings`: an object in the shape `{ startDate, endDate, durationSeconds }`.
387
388## FAQ
389
390* Process exited with code *null*?
391
392 From [Node child_process documentation](http://nodejs.org/api/child_process.html#child_process_event_exit), `exit` event:
393
394 > This event is emitted after the child process ends. If the process
395 > terminated normally, code is the final exit code of the process,
396 > otherwise null. If the process terminated due to receipt of a signal,
397 > signal is the string name of the signal, otherwise null.
398
399
400 So *null* means the process didn't terminate normally. This will make **concurrent**
401 to return non-zero exit code too.
402
403* Does this work with the npm-replacements [yarn](https://github.com/yarnpkg/yarn) or [pnpm](https://pnpm.js.org/)?
404
405 Yes! In all examples above, you may replace "`npm`" with "`yarn`" or "`pnpm`".