You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Electron+React中如何以可读形式显示带颜色的终端输出?

解决React渲染终端带颜色输出格式异常的问题

你的问题核心是终端输出里的ANSI颜色转义码(比如\x1b[32m这类控制字符)在HTML中无法被解析,直接显示成乱码,导致DOM渲染异常。下面是具体的解决方法:

一、核心思路

把终端输出中的ANSI转义码转换成HTML可识别的样式标签(比如<span style="color: green;">),再通过React渲染到DOM中。

二、具体实现

方案1:使用成熟库处理ANSI转义码(推荐)

用ansi-to-html库可以一键转换所有常见的ANSI格式(颜色、加粗、下划线等),步骤如下:

  1. 安装依赖
npm install ansi-to-html
  1. 修改React组件代码
    修正原代码中useState声明在组件外部的错误,同时添加转义码处理逻辑:
import Titlebar from "./components/Titlebar/Titlebar"
import { useState, useEffect } from "react"
import { convert } from 'ansi-to-html';

// 初始化ANSI转HTML转换器
const ansiConverter = new convert();

export default function App() {
    const [currentShellOutput, setCurrentShellOutput] = useState([])

    useEffect(() => {
        // 组件挂载时执行命令并监听输出
        ElectronAPI.execShellCommands(["spicetify apply"])

        const handleOutput = (outputString) => {
            console.log(outputString)
            // 将ANSI转义码转为HTML字符串
            const formattedOutput = ansiConverter.toHtml(outputString)
            setCurrentShellOutput(prev => [...prev, formattedOutput])
        }

        ElectronAPI.receive("sendToRenderer/shell-output", handleOutput)

        // 组件卸载时清理监听,避免内存泄漏
        return () => {
            ElectronAPI.removeListener("sendToRenderer/shell-output", handleOutput)
        }
    }, [])

    return (
        <>
            <Titlebar></Titlebar>
            {currentShellOutput.map((output, index) => (
                // 使用dangerouslySetInnerHTML渲染转换后的HTML
                <p 
                    key={index} 
                    className="terminal-output" 
                    dangerouslySetInnerHTML={{ __html: output }}
                ></p>
            ))}
        </>
    )
}

方案2:手动编写转换函数(轻量场景)

如果不想额外安装依赖,可以自己处理常见的颜色转义码:

// 手动转换常见ANSI颜色码的函数
function ansiToHtml(text) {
    return text
        // 红色
        .replace(/\x1b\[31m/g, '<span style="color: #ff4500;">')
        // 绿色
        .replace(/\x1b\[32m/g, '<span style="color: #00ff00;">')
        // 黄色
        .replace(/\x1b\[33m/g, '<span style="color: #ffff00;">')
        // 重置格式
        .replace(/\x1b\[0m/g, '</span>')
        // 替换换行为HTML换行标签
        .replace(/\n/g, '<br>')
        // 保留空格格式
        .replace(/\s/g, '&nbsp;');
}

然后在组件中用这个函数替代ansi-to-html的转换逻辑即可。

三、样式优化(模拟终端效果)

给.terminal-output类添加CSS样式,让渲染效果更接近终端:

.terminal-output {
    font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
    background-color: #1e1e1e;
    color: #d4d4d4;
    padding: 8px 12px;
    margin: 6px 0;
    border-radius: 4px;
    white-space: pre-wrap;
    line-height: 1.4;
}

四、主进程小优化

确保命令输出的编码正确,避免乱码:

shellProcess.stdout.on("data", (data) => {
    mainWindow.webContents.send("sendToRenderer/shell-output", data.toString('utf8'))
})

内容的提问来源于stack exchange,提问作者Raghavan Vidhyasagar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 06:15:45