node js cli STDOUT STDERR output exec and spawn commands

231 Views Asked by At

I am looking for a clear answer on how the stdout and stderr work when developing a npm cli module.

I would like to print out everything exactly as it is when I run command with child_process.spawn.

I managed to output the git clone command with the --progress options. Now I want to output the npm install command but it is printing only the final string.

Would be nice to have a clear answer on how this work in general and what are the best practices.

This works:

import * as cp from 'child_process';

const child = cp.spawn('git', ['clone', 'ssh://myrepo...', '--progress']);
    
child.stdout.setEncoding('utf8');
child.stdout.on('data', (chunk) => {
    process.stdout.write(`${chunk}`);
});
    
child.stderr.setEncoding('utf8');
child.stderr.on('data', (chunk) => {
    process.stdout.write(`${chunk}`);
});

// BTW why git is outputing in STDERR and not in STDOUT?

However this doesn't work

const child = cp.spawn('npm', ['i', 'mymodule']);

Is there a way to make this work for each command?

1

There are 1 best solutions below

2
On BEST ANSWER

You can leave off the event handlers and encoding settings and tell spawn() to pass stdio through to the parent process.

const child = cp.spawn('npm', ['i', 'mymodule'], {stdio: 'inherit'});

Both of your commands work for me as long as the listeners are added as in your first example. Your second example only stops working for me if I leave out the event handlers. It would be interesting to know what platform you are running on, what versions of node and npm you are using, and a complete not-working example that can be cut and paste into a file for testing. (Also, what is the name of the file? Are you using .mjs extension or something else to make import work? Is this file in a module loaded elsewhere or in the base level script?)