覆盖多个先前的终端输出

时间:2018-08-14 20:14:24

标签: javascript node.js webpack-dev-server readline

我有一个webpack-dev-server代理,并且我想在服务器运行时在终端窗口中显示对代理的请求。使这个问题复杂化的是,我想在收到请求时显示该请求,然后在收到响应后将状态代码更新为最初写入的内容。例如,如果我请求GET / foo,我希望最初显示它:

(---) GET /foo

然后,如果代理返回200响应状态,则我希望控制台输出像这样更新:

(200) GET /foo

我有这个(主要是)与此有关的:

const readline = require('readline');
// ...
devServer: {
    proxy: {
        onProxyReq: function (proxyReq, req, res) {
            process.stdout.write(`(---) ${req.method} ${req.url}`);
            proxyReq.on('response', function(response) {
                readline.clearLine(process.stdout, 0);
                readline.cursorTo(process.stdout, 0, null);
                process.stdout.write(`(${response.statusCode}) ${req.method} ${req.url}\n`);
            });
        }
    }
}
// ...

失败的地方是在返回任何响应之前收到多个请求,在这种情况下,输出看起来类似于以下内容:

(---) GET /foo/1(---) GET /bar/2(---) GET /baz/3
(200) GET /bar/2
(200) GET /baz/3
(200) GET /foo/1

我研究过使用readline's moveCursorcursorTo,但是我不知道如何跟踪先前写的行号。

当收到响应时,如何修改当前要跟踪的内容并覆盖正确的控制台输出行?

1 个答案:

答案 0 :(得分:1)

我认为您需要使用readline.moveCursor来将光标相对于其当前位置移动,以返回到与请求相对应的行。这也意味着您需要跟踪当前行或每次写入后始终将其移回x: 0

以下代码片段并非您所需要的,但是它演示了如何使用readline光标命令随时间覆盖现有的控制台输出。

const readline = require('readline')

let i = 0;
const next = () => {
    if (i && i%3 === 0) readline.moveCursor(process.stdout, null, -3)
    readline.cursorTo(process.stdout, 0, null);
    readline.clearLine(process.stdout, 0);
    process.stdout.write(`${i}\n`);
    i += 1;
    if (i < 9) setTimeout(next, 200);
    else console.log();
}
setTimeout(next, 200);

对于您的特定示例,我认为您想要更类似于以下内容的东西:

const readline = require('readline');
// ...
urls = [];
const rowOf = url => {
    let row = urls.indexOf(req.url);
    if (row === -1) {
        row = urls.length;
        urls.push(req.url);
    }
    return row;
}

const writeLine = (row, str) => {
    readline.moveCursor(process.stdout, null, row);
    readline.cursorTo(process.stdout, 0, null);
    readline.clearLine(process.stdout, 0);
    process.stdout.write(str);
    readline.moveCursor(process.stdout, null, -1*row);
    readline.cursorTo(process.stdout, 0, null);
}

devServer: {
    proxy: {
        onProxyReq: function (proxyReq, req, res) {
            writeLine(rowOf(req.url), `(---) ${req.method} ${req.url}`);
            proxyReq.on('response', function(response) {
                writeLine(rowOf(req.url), `(${response.statusCode}) ${req.method} ${req.url}\n`)
            });
        }
    }
}