readline输入框固定底部时Winston日志导致视觉清除问题求助
修复Winston日志输出导致Readline输入视觉截断的问题
我明白你遇到的问题了——虽然程序能正确接收完整的输入,但视觉上的截断确实很影响体验。这个问题出在自定义Winston Transport的日志输出逻辑上,咱们来一步步修复它。
问题根源
你当前的ConsoleTransport里用\x1b[2K\r清除了当前行,然后打印日志,最后调用_refreshLine()。但_refreshLine()只会重新渲染提示符,不会恢复用户已经输入的内容,所以就出现了输入字符“消失”的视觉bug,好在readline的输入缓冲区其实还保留着完整内容,只是显示出了问题。
修复方案
我们需要在输出日志前,先保存用户当前的输入状态(已输入的内容、光标位置),输出日志后再恢复这些状态,这样就能保证输入内容在日志输出后依然完整显示。
修改后的logger.js代码如下:
const winston = require("winston"); class ConsoleTransport extends require("winston-transport") { log(info, callback) { setImmediate(() => { this.emit('logged', info); }); // 保存当前用户的输入状态 const currentLine = this.cli.line; const currentCursor = this.cli.cursor; // 清除当前行,打印日志 this.cli.output.write('\x1b[2K\r'); console.log(info.message); // 恢复输入状态:重新设置提示符、输入内容和光标位置 this.cli._setPrompt(this.cli._prompt); this.cli.line = currentLine; this.cli.cursor = currentCursor; this.cli._refreshLine(); callback(); } } module.exports = (cli) => { let consoleTransport = new ConsoleTransport(); consoleTransport.cli = cli; return winston.createLogger({ format: winston.format.combine( winston.format.colorize(), winston.format.simple() ), transports: [consoleTransport] }); };
关键修复点说明
- 保存输入状态:通过
this.cli.line获取用户已经输入的内容,this.cli.cursor获取当前光标位置,这两个属性是readline实例内部维护的状态。 - 恢复输入状态:在打印完日志后,把之前保存的输入内容和光标位置赋值回去,再调用
_refreshLine(),这样就能正确渲染出完整的输入内容和提示符了。
这样修改后,当新日志输出时,readline的输入框会先被清除,日志打印后,输入内容和光标位置会被完整恢复,视觉上就不会再出现截断的问题了。
内容的提问来源于stack exchange,提问作者user1910744
相关产品推荐
相关产品推荐

