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 |
|
8 | Run multiple commands concurrently.
|
9 | Like `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 | - [Programmatic Usage](#programmatic-usage)
|
19 | - [`concurrently(commands[, options])`](#concurrentlycommands-options)
|
20 | - [FAQ](#faq)
|
21 |
|
22 | ## Why
|
23 |
|
24 | I like [task automation with npm](https://github.com/substack/blog/blob/master/npm_run.markdown)
|
25 | but the usual way to run multiple commands concurrently is
|
26 | `npm run watch-js & npm run watch-css`. That's fine but it's hard to keep
|
27 | on track of different outputs. Also if one process fails, others still keep running
|
28 | and you won't even notice the difference.
|
29 |
|
30 | Another option would be to just run all commands in separate terminals. I got
|
31 | tired of opening terminals and made **concurrently**.
|
32 |
|
33 | **Features:**
|
34 |
|
35 | * Cross platform (including Windows)
|
36 | * Output is easy to follow with prefixes
|
37 | * With `--kill-others` switch, all commands are killed if one dies
|
38 | * Spawns commands with [spawn-command](https://github.com/mmalecki/spawn-command)
|
39 |
|
40 | ## Install
|
41 |
|
42 | The tool is written in Node.js, but you can use it to run **any** commands.
|
43 |
|
44 | ```bash
|
45 | npm install -g concurrently
|
46 | ```
|
47 |
|
48 | or if you are using it from npm scripts:
|
49 |
|
50 | ```bash
|
51 | npm install concurrently --save
|
52 | ```
|
53 |
|
54 | ## Usage
|
55 |
|
56 | Remember to surround separate commands with quotes:
|
57 | ```bash
|
58 | concurrently "command1 arg" "command2 arg"
|
59 | ```
|
60 |
|
61 | Otherwise **concurrently** would try to run 4 separate commands:
|
62 | `command1`, `arg`, `command2`, `arg`.
|
63 |
|
64 | In package.json, escape quotes:
|
65 |
|
66 | ```bash
|
67 | "start": "concurrently \"command1 arg\" \"command2 arg\""
|
68 | ```
|
69 |
|
70 | NPM run commands can be shortened:
|
71 |
|
72 | ```bash
|
73 | concurrently "npm:watch-js" "npm:watch-css" "npm:watch-node"
|
74 |
|
75 | # Equivalent to:
|
76 | concurrently -n watch-js,watch-css,watch-node "npm run watch-js" "npm run watch-css" "npm run watch-node"
|
77 | ```
|
78 |
|
79 | NPM shortened commands also support wildcards. Given the following scripts in
|
80 | package.json:
|
81 |
|
82 | ```javascript
|
83 | {
|
84 | //...
|
85 | "scripts": {
|
86 | // ...
|
87 | "watch-js": "...",
|
88 | "watch-css": "...",
|
89 | "watch-node": "...",
|
90 | // ...
|
91 | },
|
92 | // ...
|
93 | }
|
94 | ```
|
95 |
|
96 | ```bash
|
97 | concurrently "npm:watch-*"
|
98 |
|
99 | # Equivalent to:
|
100 | concurrently -n js,css,node "npm run watch-js" "npm run watch-css" "npm run watch-node"
|
101 |
|
102 | # Any name provided for the wildcard command will be used as a prefix to the wildcard
|
103 | # part of the script name:
|
104 | concurrently -n w: npm:watch-*
|
105 |
|
106 | # Equivalent to:
|
107 | concurrently -n w:js,w:css,w:node "npm run watch-js" "npm run watch-css" "npm run watch-node"
|
108 | ```
|
109 |
|
110 | Good frontend one-liner example [here](https://github.com/kimmobrunfeldt/dont-copy-paste-this-frontend-template/blob/5cd2bde719654941bdfc0a42c6f1b8e69ae79980/package.json#L9).
|
111 |
|
112 | Help:
|
113 |
|
114 | ```
|
115 |
|
116 | concurrently [options] <command ...>
|
117 |
|
118 | General
|
119 | -m, --max-processes How many processes should run at once.
|
120 | New processes only spawn after all restart tries of a
|
121 | process. [number]
|
122 | -n, --names List of custom names to be used in prefix template.
|
123 | Example names: "main,browser,server" [string]
|
124 | --name-separator The character to split <names> on. Example usage:
|
125 | concurrently -n "styles|scripts|server" --name-separator
|
126 | "|" [default: ","]
|
127 | -r, --raw Output only raw output of processes, disables
|
128 | prettifying and concurrently coloring. [boolean]
|
129 | -s, --success Return exit code of zero or one based on the success or
|
130 | failure of the "first" child to terminate, the "last
|
131 | child", or succeed only if "all" child processes
|
132 | succeed.
|
133 | [choices: "first", "last", "all"] [default: "all"]
|
134 | --no-color Disables colors from logging [boolean]
|
135 | --hide Comma-separated list of processes to hide the output.
|
136 | The processes can be identified by their name or index.
|
137 | [string] [default: ""]
|
138 |
|
139 | Prefix styling
|
140 | -p, --prefix Prefix used in logging for each process.
|
141 | Possible values: index, pid, time, command, name,
|
142 | none, or a template. Example template: "{time}-{pid}"
|
143 | [string] [default: index or name (when --names is set)]
|
144 | -c, --prefix-colors Comma-separated list of chalk colors to use on
|
145 | prefixes. If there are more commands than colors, the
|
146 | last color will be repeated.
|
147 | - Available modifiers: reset, bold, dim, italic,
|
148 | underline, inverse, hidden, strikethrough
|
149 | - Available colors: black, red, green, yellow, blue,
|
150 | magenta, cyan, white, gray, or any hex values for
|
151 | colors, eg #23de43
|
152 | - Available background colors: bgBlack, bgRed,
|
153 | bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite
|
154 | See https://www.npmjs.com/package/chalk for more
|
155 | information. [string] [default: "reset"]
|
156 | -l, --prefix-length Limit how many characters of the command is displayed
|
157 | in prefix. The option can be used to shorten the
|
158 | prefix when it is set to "command"
|
159 | [number] [default: 10]
|
160 | -t, --timestamp-format Specify the timestamp in moment/date-fns format.
|
161 | [string] [default: "yyyy-MM-dd HH:mm:ss.SSS"]
|
162 |
|
163 | Input handling
|
164 | -i, --handle-input Whether input should be forwarded to the child
|
165 | processes. See examples for more information.[boolean]
|
166 | --default-input-target Identifier for child process to which input on stdin
|
167 | should be sent if not specified at start of input.
|
168 | Can be either the index or the name of the process.
|
169 | [default: 0]
|
170 |
|
171 | Killing other processes
|
172 | -k, --kill-others kill other processes if one exits or dies [boolean]
|
173 | --kill-others-on-fail kill other processes if one exits with non zero status
|
174 | code [boolean]
|
175 |
|
176 | Restarting
|
177 | --restart-tries How many times a process that died should restart.
|
178 | Negative numbers will make the process restart forever.
|
179 | [number] [default: 0]
|
180 | --restart-after Delay time to respawn the process, in milliseconds.
|
181 | [number] [default: 0]
|
182 |
|
183 | Options:
|
184 | -h, --help Show help [boolean]
|
185 | -v, -V, --version Show version number [boolean]
|
186 |
|
187 | Examples:
|
188 |
|
189 | - Output nothing more than stdout+stderr of child processes
|
190 |
|
191 | $ concurrently --raw "npm run watch-less" "npm run watch-js"
|
192 |
|
193 | - Normal output but without colors e.g. when logging to file
|
194 |
|
195 | $ concurrently --no-color "grunt watch" "http-server" > log
|
196 |
|
197 | - Custom prefix
|
198 |
|
199 | $ concurrently --prefix "{time}-{pid}" "npm run watch" "http-server"
|
200 |
|
201 | - Custom names and colored prefixes
|
202 |
|
203 | $ concurrently --names "HTTP,WATCH" -c "bgBlue.bold,bgMagenta.bold"
|
204 | "http-server" "npm run watch"
|
205 |
|
206 | - Configuring via environment variables with CONCURRENTLY_ prefix
|
207 |
|
208 | $ CONCURRENTLY_RAW=true CONCURRENTLY_KILL_OTHERS=true concurrently "echo hello" "echo world"
|
209 |
|
210 | - Send input to default
|
211 |
|
212 | $ concurrently --handle-input "nodemon" "npm run watch-js"
|
213 | rs # Sends rs command to nodemon process
|
214 |
|
215 | - Send input to specific child identified by index
|
216 |
|
217 | $ concurrently --handle-input "npm run watch-js" nodemon
|
218 | 1:rs
|
219 |
|
220 | - Send input to specific child identified by name
|
221 |
|
222 | $ concurrently --handle-input -n js,srv "npm run watch-js" nodemon
|
223 | srv:rs
|
224 |
|
225 | - Shortened NPM run commands
|
226 |
|
227 | $ concurrently npm:watch-node npm:watch-js npm:watch-css
|
228 |
|
229 | - Shortened NPM run command with wildcard (make sure to wrap it in quotes!)
|
230 |
|
231 | $ concurrently "npm:watch-*"
|
232 |
|
233 | For more details, visit https://github.com/open-cli-tools/concurrently
|
234 | ```
|
235 |
|
236 | ## Programmatic Usage
|
237 | concurrently can be used programmatically by using the API documented below:
|
238 |
|
239 | ### `concurrently(commands[, options])`
|
240 |
|
241 | - `commands`: an array of either strings (containing the commands to run) or objects
|
242 | with the shape `{ command, name, prefixColor, env, cwd }`.
|
243 |
|
244 | - `options` (optional): an object containing any of the below:
|
245 | - `cwd`: the working directory to be used by all commands. Can be overriden per command.
|
246 | Default: `process.cwd()`.
|
247 | - `defaultInputTarget`: the default input target when reading from `inputStream`.
|
248 | Default: `0`.
|
249 | - `handleInput`: when `true`, reads input from `process.stdin`.
|
250 | - `inputStream`: a [`Readable` stream](https://nodejs.org/dist/latest-v10.x/docs/api/stream.html#stream_readable_streams)
|
251 | 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`.
|
252 | - `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)).
|
253 | - `killOthers`: an array of exitting conditions that will cause a process to kill others.
|
254 | Can contain any of `success` or `failure`.
|
255 | - `maxProcesses`: how many processes should run at once.
|
256 | - `outputStream`: a [`Writable` stream](https://nodejs.org/dist/latest-v10.x/docs/api/stream.html#stream_writable_streams)
|
257 | to write logs to. Default: `process.stdout`.
|
258 | - `prefix`: the prefix type to use when logging processes output.
|
259 | Possible values: `index`, `pid`, `time`, `command`, `name`, `none`, or a template (eg `[{time} process: {pid}]`).
|
260 | Default: the name of the process, or its index if no name is set.
|
261 | - `prefixColors`: a list of colors as supported by [chalk](https://www.npmjs.com/package/chalk).
|
262 | If concurrently would run more commands than there are colors, the last color is repeated.
|
263 | Prefix colors specified per-command take precedence over this list.
|
264 | - `prefixLength`: how many characters to show when prefixing with `command`. Default: `10`
|
265 | - `raw`: whether raw mode should be used, meaning strictly process output will
|
266 | be logged, without any prefixes, colouring or extra stuff.
|
267 | - `successCondition`: the condition to consider the run was successful.
|
268 | 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.
|
269 | Anything else means all processes should exit successfully.
|
270 | - `restartTries`: how many attempts to restart a process that dies will be made. Default: `0`.
|
271 | - `restartDelay`: how many milliseconds to wait between process restarts. Default: `0`.
|
272 | - `timestampFormat`: a [date-fns format](https://date-fns.org/v2.0.1/docs/format)
|
273 | to use when prefixing with `time`. Default: `yyyy-MM-dd HH:mm:ss.ZZZ`
|
274 |
|
275 | > Returns: a `Promise` that resolves if the run was successful (according to `successCondition` option),
|
276 | > or rejects, containing an array of objects with information for each command that has been run, in the order
|
277 | > that the commands terminated. The objects have the shape `{ command, index, exitCode, killed }`, where `command` is the object
|
278 | > passed in the `commands` array, `index` its index there and `killed` indicates if the process was killed as a result of
|
279 | > `killOthers`. Default values (empty strings or objects) are returned for the fields that were not specified.
|
280 |
|
281 | Example:
|
282 |
|
283 | ```js
|
284 | const concurrently = require('concurrently');
|
285 | concurrently([
|
286 | 'npm:watch-*',
|
287 | { command: 'nodemon', name: 'server' },
|
288 | { command: 'deploy', name: 'deploy', env: { PUBLIC_KEY: '...' } },
|
289 | { command: 'watch', name: 'watch', cwd: path.resolve(__dirname, 'scripts/watchers')}
|
290 | ], {
|
291 | prefix: 'name',
|
292 | killOthers: ['failure', 'success'],
|
293 | restartTries: 3,
|
294 | cwd: path.resolve(__dirname, 'scripts'),
|
295 | }).then(success, failure);
|
296 | ```
|
297 |
|
298 | ## FAQ
|
299 |
|
300 | * Process exited with code *null*?
|
301 |
|
302 | From [Node child_process documentation](http://nodejs.org/api/child_process.html#child_process_event_exit), `exit` event:
|
303 |
|
304 | > This event is emitted after the child process ends. If the process
|
305 | > terminated normally, code is the final exit code of the process,
|
306 | > otherwise null. If the process terminated due to receipt of a signal,
|
307 | > signal is the string name of the signal, otherwise null.
|
308 |
|
309 |
|
310 | So *null* means the process didn't terminate normally. This will make **concurrent**
|
311 | to return non-zero exit code too.
|
312 |
|
313 | * Does this work with the npm-replacements [yarn](https://github.com/yarnpkg/yarn) or [pnpm](https://pnpm.js.org/)?
|
314 |
|
315 | Yes! In all examples above, you may replace "`npm`" with "`yarn`" or "`pnpm`".
|