Back to Blog

asdad

1/1/2026
2 min read
356 views

在 Monaco Editor 中实现类似 VS Code 的终端,通常需要结合 Xterm.js(用于渲染终端界面)和 WebContainerPty.js(用于提供底层 Shell 环境)。

由于 Monaco 本身只是一个代码编辑器,并不包含终端模拟器,你需要手动集成以下两个组件:


1. 技术组合建议

组件

推荐工具

作用

终端 UI (前端)

xterm.js

负责在网页上渲染黑底白字的命令行界面。

底层环境 (核心)

WebContainer (浏览器内) 或 node-pty (服务端)

负责执行命令并将结果通过数据流传给 UI。

交互组件

xterm-addon-fit

自动调整终端大小以适配容器宽度。


2. 实现方案:浏览器本地终端 (WebContainer)

如果你希望实现“纯网页版”的终端(不依赖后端服务器),目前最主流的方案是使用 StackBlitz 的 WebContainer。它可以在浏览器内运行一个微型的 Node.js 环境。

实现代码示例:

TypeScript

auto
import { Terminal } from 'xterm';
import { FitAddon } from 'xterm-addon-fit';
import { WebContainer } from '@webcontainer/api';
import 'xterm/css/xterm.css';

async function initTerminal() {
    // 1. 初始化 Xterm.js UI
    const term = new Terminal({
        cursorBlink: true,
        theme: { background: '#1e1e1e' }
    });
    const fitAddon = new FitAddon();
    term.loadAddon(fitAddon);
    
    const terminalElement = document.getElementById('terminal-container');
    if (terminalElement) {
        term.open(terminalElement);
        fitAddon.fit();
    }

    // 2. 启动 WebContainer (本地沙盒环境)
    const webcontainerInstance = await WebContainer.boot();
    
    // 3. 启动一个 Shell 会话
    const shellProcess = await webcontainerInstance.spawn('jsh'); // jsh 是内置的简易 shell
    
    // 4. 将 Shell 输出流向终端显示
    shellProcess.output.pipeTo(new WritableStream({
        write(data) {
            term.write(data);
        }
    }));

    // 5. 将终端输入流向 Shell 执行
    const input = shellProcess.input.getWriter();
    term.onData((data) => {
        input.write(data);
    });
}

3. 实现方案:远程服务器终端 (Node-pty)

如果你希望终端运行在真正的服务器上(例如你的 Python 或 Go 编译环境),你需要通过 WebSocket 转发数据:

  1. 后端 (Node.js):使用 node-pty 开启一个系统终端进程(如 /bin/bash)。

  2. 通信:通过 WebSocket 将 pty.stdout 发送给前端,并将前端的按键数据传回 pty.stdin

  3. 前端:使用 xterm.js 接收并渲染这些二进制流。


4. 样式调整:模仿 VS Code 的布局

为了看起来更像 VS Code,你可以使用分栏布局:

  • 顶部/左侧:Monaco Editor 容器。

  • 底部:一个固定高度(如 200px)的 div 作为 terminal-container

  • 拖拽:使用类似 react-resizablesplit.js 的库来实现编辑器和终端之间的高处自由拖动。

下一步建议

既然你已经跑通了 Python 的 LSP,最简单的方案是在你的 Node.js 后端启动一个 node-pty 进程

你需要我为你提供一个配套的 Node.js 后端代码,通过 WebSocket 将系统终端接入你的编辑器吗?

Thanks for reading!

Related Articles

Comments

Please sign in to join the conversation.

Loading content...