REPL
一个带语法高亮、历史记录和自动补全功能的交互式 JavaScript 和 TypeScript REPL
bun repl 会启动一个用于求值 JavaScript 和 TypeScript 表达式的交互式读取-求值-打印循环(REPL)。用它来测试代码片段、探索 API,并进行调试。
bun repl
欢迎使用 Bun v1.3.3
输入 .copy [code] 以复制到剪贴板。输入 .help 了解更多信息。
> 1 + 1
2
> const greeting = "Hello, Bun!"
undefined
> greeting
'Hello, Bun!'
功能
- TypeScript & JSX — 直接编写 TypeScript 和 JSX。Bun 会即时转译所有内容。
- 顶层
await— 在提示符中直接等待 Promise,无需将其包装在异步函数中。 - 语法高亮 — REPL 会在你输入时高亮显示内容。
- 持久化历史记录 — REPL 会将历史记录保存到
~/.bun_repl_history。历史记录会在不同会话之间保留。 - Tab 自动补全 — 按
Tab补全属性名和 REPL 命令。 - 多行输入 — 未闭合的方括号、大括号和圆括号会自动在下一行继续。
- Node.js 全局变量 —
require、module、__dirname和__filename均可用,并且会相对于当前工作目录解析。
特殊变量
REPL 会暴露两个特殊变量,每次求值后会更新。
| 变量 | 说明 |
|---|---|
_ | 上一个表达式的结果 |
_error | 上一次抛出的错误 |
> 2 + 2
4
> _ * 10
40
> JSON.parse("oops")
SyntaxError: JSON Parse error: Unexpected identifier "oops"
> _error
SyntaxError: JSON Parse error: Unexpected identifier "oops"
顶层 await
你可以直接在提示符中对任意表达式使用 await。
> await fetch("https://api.github.com/repos/oven-sh/bun").then(r => r.json()).then(r => r.stargazers_count)
81234
> const response = await fetch("https://example.com")
undefined
> response.status
200
导入模块
与 Bun 运行时一样,REPL 同时接受 require 和 import:你可以在提示符中自由混用 ES 模块和 CommonJS。模块解析使用与 bun run 相同的规则,因此你可以从 node_modules、相对路径或 node: 内置模块导入。
> import { z } from "zod"
undefined
> const path = require("path")
undefined
> z.string().parse(path.join("/tmp", "file.txt"))
'/tmp/file.txt'
声明在整个会话期间都会保留。与常规脚本不同,你可以在多次求值之间重新声明 const/let,因此在迭代过程中可以重新运行 import 和 require 语句。
多行输入
当你在未闭合括号、大括号或圆括号的行按下 Enter,REPL 会自动换行继续。提示符变为 ... 表示续行。
> function add(a, b) {
... return a + b;
... }
undefined
> add(2, 3)
5
对于更长的多行输入,使用 .editor 进入编辑器模式,所有输入会缓冲直到按 Ctrl+D。
REPL 命令
在提示符输入 .help 查看所有可用的 REPL 命令。
| 命令 | 说明 |
|---|---|
.help | 打印帮助信息,列出命令和快捷键 |
.exit | 退出 REPL |
.clear | 清屏 |
.copy | 复制最近结果到剪贴板。也可以传入表达式计算并复制:.copy 1 + 1 |
.load | 加载文件到 REPL 会话:.load ./script.ts |
.save | 将当前 REPL 历史保存到文件:.save ./session.txt |
.editor | 进入多行编辑器模式(按 Ctrl+D 执行,Ctrl+C 取消) |
.break | 取消当前多行输入 |
.history | 打印命令历史 |
快捷键
REPL 支持 Emacs 风格的行编辑。
| 快捷键 | 功能 |
|---|---|
Ctrl+A | 移动光标至行首 |
Ctrl+E | 移动光标至行尾 |
Ctrl+B / Ctrl+F | 向后/向前移动一个字符 |
Alt+B / Alt+F | 向后/向前移动一个单词 |
Ctrl+U | 删除至行首 |
Ctrl+K | 删除至行尾 |
Ctrl+W | 向后删除一个单词 |
Ctrl+D | 删除字符(行为空时退出) |
Ctrl+L | 清屏 |
Ctrl+T | 交换光标前两个字符 |
上箭头 / 下箭头 | 浏览历史 |
Tab | 自动补全 |
Ctrl+C | 取消当前输入(空行时连续按两次退出) |
历史记录
REPL 会自动将历史记录保存到 ~/.bun_repl_history(最多 1000 条),并在每次会话开始时加载。使用 上箭头/下箭头 浏览历史记录。
若要导出历史到其它文件,使用 .save:
> .save ./my-session.txt
非交互模式
使用 -e / --eval 以 REPL 语义执行脚本并退出。使用 -p / --print 除执行外会打印结果。
bun repl -e "const x: number = 42; console.log(x)"
# 42
bun repl -p "await fetch('https://example.com').then(r => r.status)"
# 200
bun repl -p "{ a: 1, b: 2 }"
# { a: 1, b: 2 }
这两个标志使用与交互式 REPL 相同的转换,因此 Bun 会将裸对象字面量(如 { a: 1 })视为对象表达式,而不是块语句。事件循环清空后进程会退出(待处理的定时器和 I/O 会先完成)。发生错误时,进程会以代码 1 退出。