I often have projects where I have multiple development tasks that need to be running while I work. My worst offender actually has four.
- the main web server
- an api web server
- webpack
- a grunt task that copies some files
I’ll spare you the details of why it’s such a mess.
I got tired of making several terminals to spin up all those tasks. My first attempt at a solution was to use a bash script that looked something like this.
#!/usr/bin/env bash
node server.js &
node api.js &
npx webpack &
npx grunt watch &
The problem with this is that you end up with orhaned processes when you ctrl+c
kill it.
Killing Orphaned Processes
Killing the orphans isn’t so hard.
ps aux | grep node
Find the pids.
kill [pid]
But that’s using up more time than just having 4 separate terminals.
Use Node.js and child_process.spawn
Then I found a solution that worked. Write some Node.js that uses child_process.spawn
to spawn my tasks as separate processes.
I worked out good defaults that make life easy:
- include my path
- spawn a bash shell
- use the current working directory
- inherit
stdin
,stdout
andstderr
It looked a bit like this.
#!/usr/bin/env node
'use strict';
var path = require('path');
function spawn({ cmd, cwd }) {
return require('child_process').spawn(cmd, {
env: {
PATH: process.env.PATH
},
shell: true,
stdio: ['inherit', 'inherit', 'inherit'],
cwd: cwd || process.cwd()
});
}
spawn({ cmd: `node server.js` });
spawn({ cmd: `node api.js` });
spawn({
cmd: 'npx webpack --config webpack.development.js --watch --colors',
cwd: path.join(__dirname, 'assets')
});
spawn({ cmd: `npx grunt watch` });
Spawn in Parallel
It worked. I’m going to use this on many projects, so I made it a library.
tl;dr
Check out spawn-in-parallel.
Install.
npm install --save-dev @ryanburnette/spawn-in-parallel
Set up a development script.
mkdir -p scripts
touch scripts/development
chmod +x scripts/development
It’ll look something like this.
#!/usr/bin/env node
'use strict';
require('@ryanburnette/spawn-in-parallel')([
'node server.js',
'node api.js',
'npx webpack',
'npx grunt watch'
]);
Get to work.
scripts/development
When you’re done, ctrl+c
kill it with no orphaned processes.