在浏览器中运行虚拟机

334 阅读4分钟

超越标签:探索现代网页功能

第1集

我们将在你的浏览器中运行一个完整的虚拟机!不仅仅是运行虚拟机——我们还会启动 FreeDOS 和 Alpine Linux。“等一下,什么?我们已经有 VirtualBox、VMware 和 DOSBox 来处理这些东西!” 那么,当你有浏览器时,谁还需要 VirtualBox?(开个玩笑!)

但说真的,让我们来展示现代浏览器变得多么强大,特别是现在它们支持 WebAssembly(Wasm)。当然,传统的虚拟机软件很棒,但能够在浏览器中运行整个操作系统?那简直太酷了!

如果你想跳到成品,可以在这里找到完成的代码:github.com/nadchif/in-…

在本指南中,我们将使用 React.js,但我会保持内容通用,以便你可以将其适应为普通 HTML 或任何你喜欢的框架。

你需要的东西

  • 基本的 HTML、Javascript 和 CSS 知识
  • 支持 WebAssembly 的网页浏览器。别担心,你现在使用的浏览器可能就能工作。
  • 安装了 Node.js。你可以在 这里 下载并按照安装步骤进行。

好吧,让我们开始构建这个东西吧!

1. 设置我们的 Web 应用

如果你已经是 React 专家,可以跳过设置,直接跳到组件部分!

首先,使用 Vite 创建我们的应用(它超级快速和现代):

npm create vite@latest

当它问你时:

  • 选择一个项目名称(我选择“browser-vm”)
  • 选择 React 作为框架。
  • 选择 Javascript 作为变体。(保持通用,正如我承诺的)
  • 然后运行:
cd browser-vm
npm install

组件

现在让我们设置我们的虚拟机显示。打开 App.jsx,将所有内容替换为以下内容:

function App() {
    return (
        <div id="screen_container">
            <div id="screen" style={{ overflow: 'hidden' }}>初始化模拟器…</div>
            <canvas style={{ display: 'none' }}></canvas>
        </div>
    );
}
export default App;

打开 index.css,将内容替换为:

#screen_container {
    white-space: pre;
    font-family: Courier, monospace;
    font-size: 14px;
    line-height: 14px;
    background-color: #000;
    color: #fff;
}

2. 准备我们的虚拟机

我们使用一个很酷的项目叫 V86,它将你的浏览器变成一个真正的计算机模拟器。它使用 WebAssembly 即时翻译计算机指令——相当不错,对吧?更多信息请见 这里

从 V86 的 GitHub 发布页面 下载以下文件:

接下来,从 V86 仓库的 bios 文件夹 下载以下 BIOS 文件:

将它们放入你的项目中,如下所示:

public/
├── v86.wasm
├── libv86.js
└── bios/
    ├── seabios.bin
    └── vgabios.bin

3. 让它工作吧!

更新你的 index.html,通过添加 <script src="libv86.js"></script> 来包含我们的虚拟机引擎:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>FreeDOS 1.2</title>
</head>
<body>
    <div id="root"></div>
    <script src="libv86.js"></script>
    <script type="module" src="/src/main.jsx"></script>
</body>
</html>

现在是有趣的部分——让我们配置我们的虚拟机!更新 App.jsx 的内容为:

import { useEffect } from 'react';
function App() {
    useEffect(function initializeEmulator() {
        // 见 https://github.com/copy/v86/blob/master/src/browser/starter.js 获取选项
        window.emulator = new window.V86({
            wasm_path: '/v86.wasm',
            screen_container: document.getElementById("screen_container"),
            bios: {
                url: "/bios/seabios.bin",
            },
            vga_bios: {
                url: "/bios/vgabios.bin",
            },
            hda: { // 硬盘
                url: "/images/fd12-base.img",
                async: true,
                size: 419430400, // 推荐在 URL 中添加图像的大小。见 https://github.com/copy/v86/blob/master/src/browser/starter.js 
            },
            autostart: true,
        });
    }, []);
    
    return (
        <div id="screen_container">
            <div id="screen" style={{ overflow: 'hidden' }}>初始化模拟器…</div>
            <canvas style={{ display: 'none' }}></canvas>
        </div>
    );
}
export default App;

有关可用模拟器选项的更多详细信息,请查看:github.com/copy/v86/bl…

启动操作系统!

首先:FreeDOS

让我们从有趣的开始——FreeDOS! 它非常适合运行经典的 DOS 游戏和软件。获取 预构建版本在这里,解压 fd12-base.img,并将其放入 public/images 文件夹中。

通过运行以下命令启动 Web 应用:

npm run dev

然后在浏览器中打开 http://localhost:5173/

在浏览器中打开 http://localhost:5173/

https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft8sl9ox92t18trb0w3c3.gif

想尝试 Linux 吗?

还有更酷的事情——我们可以直接在浏览器中运行 Alpine Linux!下载 最新的 Alpine 虚拟 ISO,并更新你的虚拟机设置如下:

window.emulator = new window.V86({
    wasm_path: '/v86.wasm',
    screen_container: document.getElementById("screen_container"),
    bios: {
        url: "/bios/seabios.bin",
    },
    vga_bios: {
        url: "/bios/vgabios.bin",
    },
    boot_order: '0x123', // 优先从 CD-ROM 启动
    memory_size: 512 * 1024 * 1024, // 512MB RAM
    vga_memory_size: 64 * 1024 * 1024, // 64MB VGA RAM
    // 更多信息见:https://github.com/copy/v86/blob/master/docs/networking.md
    net_device: {
        type: 'virtio',
        relay_url: "wisps://wisp.mercurywork.shop",
    },
    cdrom: {
        // 来源:https://dl-cdn.alpinelinux.org/alpine/v3.20/releases/x86/alpine-virt-3.20.3-x86.iso
        url: "/images/alpine-virt-3.20.3-x86.iso", 
    },
    autostart: true,
});

刷新浏览器,等待 Linux 启动。这可能需要 3-5 分钟。

https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz82pw0varmts2ipon6o9.jpeg

让它看起来更酷

想要那种复古计算机的真实感吗?让我们添加完美的字体:

  • 获取 现代 DOS 字体
  • 将文件放入你的项目的 assets/fonts/ModernDOS 中,并更新 index.css 为:
@font-face {
    font-family: 'ModernDOS';
    src: url('./assets/fonts/ModernDOS/ModernDOS8x16.ttf') format('truetype');
}
#screen_container {
    white-space: pre;
    font-family: 'ModernDOS', 'Courier New', Courier, monospace;
    font-size: 14px;
    line-height: 14px;
    background-color: #000;
    color: #fff;
}

刷新页面,享受新外观!

使用 DOS 样式字体的浏览器中运行的 FreeDOS

接下来做什么?

现在你在浏览器中运行了一个虚拟机(这太酷了!),这里有一些有趣的事情可以尝试:

想要完整的代码吗?在这里获取:

相似的酷东西可以查看

大感谢