In npm, how can I run two or more parallel tasks, but waiting for the resource that the first task will create to be available to the second task to use it, and so forth?
example (conceptual):
npm run task1 & waitfor task1 then task2 & waitFor task3 then task4 ...
any ideas?
EDIT
As an example: Lets say that my first task is starting a webserver, and my second task is consuming data from that web-server every time an event happens. Another example: My first task could be starting webdriver-manager, my second task, starting a webserver, and my third task, run e2e tests everty time my files are changed. So, I need all those tasks to keep running concurrently, but they need to be initialized in an specific order and time.
You can try concurrently with wait-on package in order to manage conccurent/sequential scripts and outputs. wait-on sequential launches support head response status, tcp listening, ...
For example :
"scripts": {
"start": "concurrently -k -n \"DB,API,WEB\" -c \"blue,magenta,yellow\" \"npm run start-db\" \"npm run start-api\" \"npm run start-web\"",
"start-db": "myDbServerCmd",
"start-api": "wait-on tcp:27017 && myApiServerCmd",
"start-web": "myFrontServerCmd",
}
Thanks dchambers for the idea (source).
I'm not sure I fully understand your requirement, so I'll provide a few possible solutions.
It may be that you are wanting to run tasks sequentially (the first solution below), however in your post you mention parallel.
1. Running Tasks sequentially
npm-scripts
supports the &&
operator which is typically used in bash shells. The &&
operator, used in npm-scripts
, does however work successfully cross-platform.
Pseudo example using the &&
operator for chaining tasks:
"scripts": {
"foo": "npm run task1 && npm run task2 && npm run task3"
},
Running $ npm run foo
via your CLI using the example above...
- Initially runs
task1
.
- When
task1
has successfully completed (i.e. task1
exits with a status of zero) then task2
will be run.
- When
task2
has successfully completed then task3
will be run.
If the left side of &&
operator fails for whatever reason, (i.e. it exits with non-zero code/status), the subsequent task(s) on the right side will fail to run. For example; if task1
fails then task2
and task3
will not run.
2. Running Tasks simultaneously
npm-scripts
also supports the single &
operator cross-platform for running tasks simultaneously.
Pseudo example using the &
operator:
"scripts": {
"foo": "npm run task1 & npm run task2 & npm run task3"
},
In this example the main difference between the double &&
and the single &
operator is that if the left side of the single &
fails, then the right side runs regardless. For example; if task1
fails then task2
still runs.
3. Running Tasks in parallel.
To run tasks in parallel I recommend you utilize parallelshell:
$ npm i -D parallelshell
Pseudo example using parallelshell
:
"scripts": {
"foo": "parallelshell \"npm run task1\" \"npm run task2\" \"npm run task3\""
},
This example initially seems very similar to using the single &
operator shown in the previous section, however it offers additional benefits as listed in the documentation. The main benefit (IMO) being:
If command1 or command2 exit with non-zero exit code, then this will not effect the outcome of your shell (i.e. they can fail and npm/bash/whatever will ignore it). parallelshell will not ignore it, and will exit with the first non-zero exit code.
4. Running Tasks in parallel and sequentially.
Lets say you want to run task1
and task2
in parallel/simultaneously and then run task3
only when both task1
and task2
have successfully completed.
To achieve this you can utilize both parallelshell
and the built-in &&
operator.
Pseudo example using parallelshell
and the &&
operator for chaining tasks:
"scripts": {
"foo": "parallelshell \"npm run task1\" \"npm run task2\" && npm run task3"
},
EDIT
A solution based on the following OP's update/edit:
Another example: My first task could be starting webdriver-manager, my second task, starting a webserver, and my third task, run e2e tests everty time my files are changed. So, I need all those tasks to keep running concurrently, but they need to be initialized in an specific order and time.
5. Running Tasks concurrently.
concurrently can be utilized to run tasks concurrently:
$ npm i -D concurrently
Pseudo example using concurrently
:
"scripts": {
"foo": "concurrently \"npm run task1\" \"npm run task2\" \"npm run task3\""
},
This example will keep all tasks (1,2, and 3) running concurrently, and they'll start in the order specified. I don't know enough detail of the tools mentioned in your example use case, however all examples provided in this post can be combined as necessary to meet your exact requirement.
concurrently
also has several useful options too.