2

I'm playing in spawning npm install -g create-react-app from a js script. I want to get in real time the part of the output, where you can see the progress of the package's installation process. I mean this:

enter image description here

But when I execute the script, the output is this when installing:

+ create-react-app@2.1.8
added 63 packages from 20 contributors in 4.885s

and this when updating:

+ create-react-app@2.1.8
updated 1 package in 1.971s

The code I'm using:

const run = (cmd, args) => {
    return new Promise((resolve, reject) => {
        const spawn = require('child_process').spawn;
        const command = spawn(cmd, args);
        let result = '';
        command.stdout.on('data', data => {
            result += data.toString()
        });
        command.on('close', _ => {
            resolve(result)
        });
        command.on('error', err => {
            reject(err)
        });
    })
}

run(npmExecutable, ["install", "-g", "create-react-app"]).then(result => {
    console.log(result);
});

So, it's possible to get the desire real time output where you can see the progress bar?

EDIT: Well, according to Mark's answer I can see now the progess bar, but how I can output this result (progress bar) in real time to stdout, I mean to a variable?

This is the new code:

const run = (cmd, args) => {
    return new Promise((resolve, reject) => {
        const spawn = require("child_process").spawn;
        const command = spawn(cmd, args, {
            stdio: "inherit"
        });
        command.on("close", _ => {
            resolve();
        });
        command.on("error", err => {
            reject(err);
        });
    });
};

EDIT ABOUT DUPLICATE: My question is different from the other one, because now I'm trying to resolve another issue using the answer (comments) I received from the other question !

robe007
  • 3,523
  • 4
  • 33
  • 59
  • Possible duplicate of [It is possible to get the progress of a spawned process from nodejs?](https://stackoverflow.com/questions/55286601/it-is-possible-to-get-the-progress-of-a-spawned-process-from-nodejs) – Jake Holzinger Mar 22 '19 at 00:48
  • No it is not. It is the next stage of that question. – robe007 Mar 22 '19 at 00:56

1 Answers1

3

NPM is avoiding the animations and progress bar when output is being directed through a pipe. Assuming this is the top level parent process, you can specify an option to direct all STDIO options to the host.

const command = spawn(cmd, args, {stdio: 'inherit'});
Mark
  • 694
  • 5
  • 15
  • Are you sure? I think this is not possible, 'cause you're _spawning_ a process. You need to intercept that _spawn process_ with a _listener_ to get the _data_ – robe007 Mar 22 '19 at 00:25
  • 1
    You are correct. I've updated my answer after reviewing the docs and giving it a test run. – Mark Mar 22 '19 at 00:44
  • 1
    How have you tried? What I get now is an error: `command.stdout.on("data", function (data) { ^ TypeError: Cannot read property 'on' of null` – robe007 Mar 22 '19 at 00:59
  • 1
    If you remove the `command.stdout.on` section, yes, it does work. If you need further clarification here is the exact code that I used with a screenshot of it running. https://imgur.com/a/kn3TnK6 – Mark Mar 22 '19 at 02:27
  • Yes, works. But the only thing now, is that I need to store this result (the progress) in a variable, in a way that I can have this progress in _real time_ to do some math with it. I don't know if this could be possible. Have you tried that? – robe007 Mar 22 '19 at 04:11
  • Do you have any info on how NPM knows whether its output is being piped or not? I'm surprised it's possible for NPM to know that and change what it outputs based on that. – Nick Manning May 09 '22 at 03:17