覆盖多个先前的终端输出
Overwriting multiple previous terminal outputs
我有一个 webpack-dev-server 代理,我想在服务器 运行 时在终端 window 中显示对代理的请求。使这变得复杂的是,我想在收到请求时显示请求,然后在收到带有状态代码的响应后更新最初编写的内容。例如,如果我要请求 GET /foo,我希望最初显示为:
(---) GET /foo
然后,如果代理 returns 响应状态为 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 moveCursor
与 cursorTo
,但我不知道如何跟踪之前写入的行号。
如何修改我当前拥有的内容以在收到响应时跟踪并覆盖正确的控制台输出行?
我认为您需要使用 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`)
});
}
}
}
我有一个 webpack-dev-server 代理,我想在服务器 运行 时在终端 window 中显示对代理的请求。使这变得复杂的是,我想在收到请求时显示请求,然后在收到带有状态代码的响应后更新最初编写的内容。例如,如果我要请求 GET /foo,我希望最初显示为:
(---) GET /foo
然后,如果代理 returns 响应状态为 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 moveCursor
与 cursorTo
,但我不知道如何跟踪之前写入的行号。
如何修改我当前拥有的内容以在收到响应时跟踪并覆盖正确的控制台输出行?
我认为您需要使用 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`)
});
}
}
}