child_process.stdout.on('data', cb) groups logs into one event

This is just a demo, not my real code. I can attach my real code if needed.

I have a scriptA which outputs logs via: process.stdout.write.
Then I want to get each log from parent scriptB with:

const cp = child_process.spawn('node', ['scriptA.js']);
cp.stdout.on('data', (data) => {
   console.log(data.toString() + '\n');
});

Which should output:

line a 

line b

line c

But it joins some lines into one (if they are output in a short period of time):

line a
line b

line c

I've tried to use timeouts in the child_process but of course it just delays them all. I also tried to use random timeouts, but that didn't work either, as it just messed up the order of the logs.

Anybody know if there is any way of overcoming this issue?

EDIT: I just thought of splitting the log in the parent, and dispatch logs by line, if more than one is present:

cp.stdout.on('data', (data) => {
  let logs = data.toString().split('\n').filter(x => x);
  logs.forEach(el => {
    console.log(`${el}\n\n`)
  });
});

This does what I want but I don't think is the best approach. Any advice helps!


Solution 1:

You can use the readline module from the standard library to do this.

const readline = require('readline');
const child_process = require('child_process');

const cp = child_process.spawn('node', ['scriptA.js']);
const reader = readline.createInterface({ input: cp.stdout })
reader.on('line', (line) => {
  console.log(line);
});

There is an option crlfDelay which you might have to tweak, which is documented in readline.createInterface()