README
🚀 Runno
Runno 是一组 JavaScript 包,用于在沙箱环境中运行多种语言的代码。它能为用户提供一个安全且便捷的代码运行环境,无需复杂的本地配置,即可在浏览器或其他 JavaScript 运行时中运行代码示例。
👨💻 使用 Runno 👉 Runno.dev
📖 文档 👉 Runno.dev
🚀 快速开始
使用 @runno/runtime
首先,将 @runno/runtime 添加到你的项目中:
npm install @runno/runtime
在你要使用 Runno 元素的地方导入 @runno/runtime,最简单的做法是在入口文件(如 main.ts 或 index.ts)中导入:
import "@runno/runtime";
导入后,你就可以在页面上使用 Runno 元素了:
<runno-run runtime="python" editor controls> print('Hello, World!') </runno-run>
不过,要使代码能够运行,你需要设置一些 HTTP 头:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
这些头信息会创建一个 跨源隔离上下文,允许使用 SharedArrayBuffer 来实现标准输入(STDIN)。
使用 @runno/sandbox
使用 npm install @runno/sandbox 安装沙箱,然后使用它来运行代码,示例如下:
import { runCode } from "@runno/sandbox";
const result = await runCode("ruby", "puts 'Hello, world!'");
if (result.resultType === "complete") {
console.log(result.stdout);
} else {
console.log("Oh no!");
}
你还可以做更复杂的事情,比如使用 runFS 针对虚拟文件系统运行代码:
function runFS(
runtime: Runtime,
entryPath: string,
fs: WASIFS,
options?: {
stdin?: string;
timeout?: number;
},
): Promise<RunResult>;
使用 @runno/wasi
使用 WASI.start 类方法是快速开始使用 Runno 的方法。它将为你设置好所需的一切并直接运行 WebAssembly 二进制文件。
请注意,这将在主线程上运行,而不是在工作线程中。因此,在运行完成之前,它会中断浏览器的任何交互操作。
import { WASI } from "@runno/wasi";
//...
const result = WASI.start(fetch("/binary.wasm"), {
args: ["binary-name", "--do-something", "some-file.txt"],
env: { SOME_KEY: "some value" },
stdout: (out) => console.log("stdout", out),
stderr: (err) => console.error("stderr", err),
stdin: () => prompt("stdin:"),
fs: {
"/some-file.txt": {
path: "/some-file.txt",
timestamps: {
access: new Date(),
change: new Date(),
modification: new Date(),
},
mode: "string",
content: "Some content for the file.",
},
},
});
你可以在 src/main.ts 中查看更完整的示例。
使用 @runno/mcp
根据你的 MCP 服务器配置,你可以通过以下方式添加 Runno:
{
"mcpServers": {
"runno": {
"command": "npx",
"args": ["@runno/mcp"]
}
}
}
✨ 主要特性
Runno 由以下几个包组成:
@runno/runtime- 用于在浏览器中运行代码示例的 Web 组件和无头工具。@runno/sandbox- 用于在 Node 和其他 JavaScript 运行时中运行代码示例的安全沙箱。@runno/wasi- 用于在沙箱中运行 WebAssembly WASI 二进制文件的同构包。@runno/mcp- 一个使用@runno/sandbox包运行代码的 MCP 服务器。
此外,还有一个已弃用的 Python 包 runno,其功能类似于沙箱包。
📦 安装指南
本地运行
如果你运气好,执行以下操作后一切应该都能正常工作:
npm install
npm run bootstrap
npm run build # 确保依赖库已构建
npm run dev
💻 使用示例
运行 WASI 二进制文件
运行时还提供了一个直接运行 WASI 二进制文件的组件:
<runno-wasi src="/ffmpeg.wasm" autorun></runno-wasi>
更多示例
在本仓库的 examples 目录中有更多关于如何使用 Runno 的示例,其中包含了一些实际使用 Runno 的方法以及如何配置它来运行代码。
📚 详细文档
@runno/runtime
访问 @runno/runtime 阅读完整文档。
@runno/wasi
访问 @runno/wasi 阅读完整文档,其中包括在工作线程中运行的说明以及虚拟文件系统的工作原理。
学习更多
你可以阅读以下介绍文章来了解更多信息:
🔧 技术细节
工作原理
Runno 使用 Web Assembly 从 JavaScript 中运行代码。代码在一个类似 Unix 的沙箱中运行,该沙箱连接到一个基于 Web 的终端模拟器。这意味着它的行为很像在 Linux 终端上本地运行代码。虽然它并不完美,但对于运行代码示例来说非常方便。
支持的运行时
该系统支持基于已发布到 WAPM 的现有包的多种运行时。这些运行时与 Runno 相关联,并且 Runno 将持续支持它们:
| 属性 | 详情 |
|------|------|
| python | 运行 Python3 代码,未固定特定版本,但至少为 3.6 |
| ruby | 运行标准 Ruby 代码,未固定版本,但至少为 3.2.0 |
| quickjs | 使用 QuickJS 引擎运行 JavaScript 代码 |
| sqlite | 运行 SQLite 命令 |
| clang | 编译并运行 C 代码 |
| clangpp | 编译并运行 C++ 代码 |
| php-cgi | 运行由 VMWare 编译的 PHP CGI 代码 |
开发相关
本仓库使用 lerna 拆分为几个包:
website- Runno 网站,包含使用说明和示例runtime- 一个库,提供 Web 组件和助手,可打包到你自己的项目中,无需使用 iframe 即可使用 Runnowasi- 一个用于在浏览器中运行 WASI 二进制文件的库sandbox- 一个用于在任何 JavaScript 运行时中运行编程语言的沙箱mcp- 一个基于sandbox构建的 MCP 服务器实现
测试
Runno 有一套小型测试,主要侧重于端到端集成测试。wasi 包拥有最广泛的测试套件,全面测试了 WASI preview1 实现。其他包主要有一些冒烟测试,以确保它们能够正常工作。
📄 许可证
Runno 是开源软件,采用 MIT 许可证,具体声明如下:
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND
关于 Runno
局限性
可用的编程语言受到已使用 WASI 编译为 Web Assembly 的工具的限制。要让更多语言可用,一个好方法是将你喜欢的编程语言工具编译为 Web Assembly 并上传到 WAPM。
WASI 不提供完整的 Linux 环境,因此大多数基于系统的接口将无法工作。在 Runno 环境中安装包和模块也很困难。如果你想导入代码,则需要在示例中提供该代码。
Runno 最适合使用标准输入(STDIN)和标准输出(STDOUT)的小代码示例,这通常是大学 CS1 课程中所教授的内容。但这并不是该系统的固有局限性!随着对 Runno 及其依赖的工具生态系统投入更多的工作,将会有更多功能可用。
安全性
Runno 的沙箱主要通过在 V8 中以 WebAssembly 形式运行代码来隔离代码。WebAssembly 具有以下一些特性:
- 执行是完全虚拟化的,它不会直接在你的 CPU 和内存上运行。
- 代码和数据是分离的,你无法跳转到数据中。
- 与外部世界的唯一接口是通过用户提供的函数。
最后一点是最重要的。如果你运行一个 WebAssembly 二进制文件而不提供任何函数,它实际上什么也做不了,就像一个没有窗户或门的盒子,什么也进不去也出不来。
Runno 的核心是 WASI preview1 的实现,它有点像一个用 TypeScript 实现的非常轻量级的操作系统。它有一个虚拟文件系统,由虚拟文件(基本上只是存储在内存中的字节数组)组成,因此它也不会访问你的真实文件系统,并且没有网络访问或其他类似功能。
如果你发现了 Runno 安全方面的漏洞,请发送邮件至 security@taybenlor.com。
特别感谢
许多开源项目和标准使得 Runno 成为可能,其中包括:
- WASI 和 WebAssembly - 来自各个工作组的许多人,特别是 Bytecode Alliance 的成员,为 WASM 和 WASI 的发展做出了贡献。非常感谢!
- XTerm.js - 一个可以在浏览器中运行的功能齐全的终端。
- CodeMirror - 一个优秀的基于 Web 的代码编辑器,集成起来总是很愉快。
- Wasmer、WAPM 和 WebAssembly.sh - Wasmer 团队为运行 Web Assembly 构建了许多优秀的工具。WebAssembly.sh 是一个很好的灵感来源和起点。
- 网络开发社区中许多人为使原生代码和 API 能够在浏览器中成功运行所做的大量工作。
感谢每一位为网络构建兼容性层的人。随着我们能够在网络上运行的新软件越来越多,网络将成为一个更好的平台!
同时,也非常感谢我的朋友们,他们忍受我不断谈论 WASM。特别感谢 Katie、Jesse、Jim、Odin、Hailey、Sam 和另一个 Sam。
Scan to contact