Bun 1.4 内置替代品:sharp、Puppeteer、node-pty 及更多
全面介绍 Bun 1.4 内置的图像处理、浏览器、Markdown、cron、终端、并行脚本及测试功能,以及如何在实际项目中安全地试用这些功能。
一个典型的 JavaScript 项目会为所需的每项功能添加相应的依赖:处理图片的 sharp、Markdown 解析器、用于浏览器自动化的 Playwright 或 Puppeteer、cron 库、用于模拟终端的 node-pty、用于并行执行脚本的 concurrently 或 npm-run-all,以及一系列用于加快测试速度的 CI 配置。Bun 1.4 则采取了不同的方式:许多这类功能可以直接内置于运行时中。本指南将通过实用的代码片段介绍这些新内置功能,同时提供一种低风险的方法来测试它们。
根据发布公告,Bun 1.4于2026年8月20日正式发布,新增了超过1,500项Node.js兼容性测试,修复了2,900多个问题,并降低了空闲状态下的CPU和内存占用。这些新API仍可能发生变化,因此请将以下内容视为阶段性信息,务必以官方的Bun 1.4发布公告及当前文档为准。此次发布的重点并非单纯提升速度,而是缩小工具链的规模。
安装或升级
Bun可以通过shell脚本、npm、Homebrew、Windows上的PowerShell,或以Docker镜像的形式进行安装。下面每行都是一种不同的安装方式,请选择适合您环境的那种:
--curl
curl -fsSL https://bun.sh/install | bash
--npm
npm install -g bun
--brew
brew install oven-sh/bun/bun
--powershell
powershell -c "irm bun.sh/install.ps1 | iex"
--docker
docker pull oven/bun
如果您的机器上已安装了Bun,只需一条命令即可升级到最新版本:
bun upgrade
使用Bun.Image进行图像处理
Bun.Image 将常见格式的解码、调整大小、旋转及编码功能集成到运行时中,因此您不再需要依赖原生图像处理库。下面的流程会读取一张 JPEG 图像,在保持宽高比的前提下将其放入 1024×1024 的矩形区域中,对其进行旋转,以 85 的质量级别将其编码为 WebP 格式,最后输出结果:
await Bun.file("photo.jpg")
.image()
.resize(1024, 1024, { fit: "inside" })
.rotate(90)
.webp({ quality: 85 })
.write("thumb.webp");
由于每一步都会返回同一个构建器,整个处理流程就像食谱一样从上到下依次执行。其典型应用包括上传缩略图、调整头像大小、将 JPEG 转换为 WebP、使用图像 API,以及在数据存储之前优化资源。
Bun 的测试表明,在包括调整 1080p PNG 图像大小及编码在内的多项基准测试中,其实现效果优于 sharp。更重要的优势在于无需使用那个常常会增加 Docker 构建及 CI 缓存复杂度的原生模块。如果您依赖 sharp 的高级功能,在切换之前请确认您要使用的功能确实存在。
使用 Bun.WebView 进行无头浏览器自动化
Bun.WebView 是一个内置的无头浏览器 API,可用于导航、点击、滚动、执行 JavaScript 代码以及截取屏幕截图。请注意 await using 的用法:它将浏览器的生命周期与所在作用域绑定,因此即使出现错误,当代码块执行完毕时浏览器也会自动被释放。
await using view = new Bun.WebView({
width: 800,
height: 600,
});
await view.navigate("https://bun.sh");
await view.click("a[href='/docs']");
const title = await view.evaluate("document.title");
await Bun.write(
"page.png",
await view.screenshot()
);
该脚本会打开一个页面,点击链接,读取文档标题并保存截图。无需构建完整的自动化框架——如截图服务、冒烟测试、数据抓取工具、运行时间检查、链接检测功能以及简单的质量保障流程——即可完成许多简单任务。当需要更底层的控制时,Bun.WebView可帮助接入 Chrome DevTools 协议。对于需要跨浏览器支持的大型端到端测试套件,专用工具可能仍是更合适的选择。
使用 Bun.markdown 渲染 Markdown
Bun.markdown可将 Markdown 转换为多种格式。最简单的转换方式是返回一个 HTML 字符串:
const html = Bun.markdown.html(
"# Hello **world**"
);
它还可以直接生成 React 元素,这在组件需要渲染 README 或文档页面时非常方便:
export default function Page() {
return Bun.markdown.react(readme);
}
渲染功能还可以进一步定制,例如为终端格式化输出。支持 GitHub 风格的 Markdown 扩展功能,如表格、任务列表、下划线标记和自动链接。这些功能非常适合文档网站、开发者门户、博客、README 查看器、CLI 帮助界面、知识库以及显示模型生成的 Markdown 的界面。
有一个注意事项比其他所有事项都重要:HTML 输出是未经过滤的。来自用户、第三方或大型语言模型的任何 Markdown 内容在到达浏览器之前都必须经过过滤处理,否则就会面临脚本注入的风险。
使用 Bun.cron 执行定时任务
Bun.cron()有两种工作模式。第一种模式下,它会将任务注册到操作系统的调度器中:Linux上的crontab、macOS上的launchd以及Windows上的任务计划程序。调用该函数时需要提供脚本路径、cron表达式和任务名称;例如,下面的代码会在每周一02:30运行一次工作进程:
await Bun.cron(
"./worker.ts",
"30 2 * * MON",
"weekly-report"
);
由于调度由操作系统管理,因此即使没有Bun进程在运行,任务也会继续执行。第二种模式下,调度逻辑存在于正在运行的进程中,此处为每五分钟触发一次任务。using声明会在其作用域结束时停止该任务:
using job = Bun.cron(
"*/5 * * * *",
async () => {
await cleanupTempFiles();
}
);
这些任务永远不会同时运行,且支持明确指定时区。适合的用途包括清理工作、生成报告、数据库维护、数据同步、批量发送邮件以及定期轮询。需注意,进程重启时其中的任务会消失;如果运行多个副本,则除非添加协调机制,否则每个副本都会执行相应任务。
并行运行脚本
bun run --parallel可替代concurrently和npm-run-all。只需传入多个脚本名称即可同时运行它们:
bun run --parallel build test
通配符模式可用于选择一组脚本:
bun run --parallel "build:*"
结合--filter使用后,该标志可在所有工作区中运行同一脚本:
bun run --parallel --filter '*' build
通常情况下一次失败就会导致所有任务停止;而--no-exit-on-error能让剩余任务继续执行,这有助于一次性收集所有测试失败情况:
bun run --parallel --no-exit-on-error --filter '*' test
每行输出前都会标注生成它的脚本,这样交织的日志依然易于阅读。在单仓库架构中,这种方式可以替代如下的顺序执行流程,让任务在多个CPU核心上并行处理:
package A → build
package B → build
package C → build
并行运行无法理解不同包之间的依赖关系,因此如果某个包必须先于另一个包构建,仍然需要指定执行顺序或使用能够处理依赖关系的任务调度器。
更快的测试运行速度
bun test增加了--parallel参数:
bun test --parallel
可以明确指定工作进程的数量:
bun test --parallel=4
文件是动态分配给各个工作进程的,而非预先分成固定批次,这样单个处理速度较慢的文件不会导致其他工作进程空闲。还有三个相关参数用于CI环境。分片功能可将测试套件分配到多台机器上,此处展示的是三个分片中的第一个:
bun test --shard=1/3
仅运行受更改影响的测试可以缩短本地反馈循环的时间:
bun test --changed
记录执行时长有助于后续运行时利用真实的计时数据来平衡工作量:
bun test --timings=timings.json
并行执行会暴露那些共享状态的测试,比如使用公共数据库、固定端口或临时文件的测试。首次启用并行执行时可能需要解决一些隔离问题。
修复易受攻击的依赖项
安全维护有内置命令可用的:
bun audit fix
该命令会将易受攻击的软件包升级到已修复的版本并安装它们。如果修复需要升级到更高主版本,Bun会报告该情况而不会自动应用;如需强制执行,可添加--latest参数。应对这些重大升级进行审查,就像处理任何破坏性变更一样。在持续集成环境中,依赖项安全检查会与常规安装步骤合并进行。
移除重复的依赖项
大型项目通常会包含同一个软件包的多个几乎相同的版本:
esbuild@0.15.10
esbuild@0.15.11
当某个版本能满足所有要求时,该命令会合并这些重复项:
bun dedupe
如果仍有重复项存在,检查机制会报错,这使其成为理想的持续集成关卡:
bun dedupe --check
重复项越少,依赖关系树就越简短,安装速度越快,磁盘占用越低,维护也更为简单,部署规模也可能更小。
使用 Bun.Terminal 驱动交互式程序
Bun.Terminal 是一个内置的伪终端,它让 JavaScript 能够在无需 node-pty 的情况下控制这类交互式程序:
bash
vim
htop
伪终端非常重要,因为当这类程序检测到真实终端时,其行为会发生变化:它们会显示全屏界面、使用颜色,并期望有键盘输入。正因如此,Bun.Terminal对于开发工具、命令行界面、终端控制面板、远程开发工具、交互式自动化系统以及人工智能编码助手而言十分重要,这些工具越来越多地直接在shell环境中运行。
Node.js兼容性及Next.js
影响最广泛的变更或许并非新的 API,而是兼容性的提升。此次发布新增了 1,517 个 Node.js 测试用例,并报告了 http、fs、stream、cluster、timers、zlib 和 vm 等模块的改进情况。此外,它在多个领域也提供了更好的支持:框架(Next.js 16、Nuxt、Fastify)、测试工具(Vitest、Playwright、Testcontainers)、可观测性工具(OpenTelemetry 以及 Datadog 的 dd-trace),还有数据或基础设施客户端(TypeORM、RabbitMQ 和 AWS S3)。
--bun 标志可强制让某个工具的 CLI 在 Bun 环境下运行,而非其 shebang 文件中指定的 Node.js 可执行文件。根据发布说明,该功能已支持 Next.js 16.3、Turbopack 以及 React Compiler:
bun --bun next build
采用新框架最终取决于现有应用能否在迁移后正常运行,因此成功构建自己的项目比任何已发布的基准测试结果都更有价值。
结合上下文的性能数据
Bun 1.4的基准测试显示,空闲状态下的CPU使用率可降低多达五倍,在HTTP任务中的内存占用显著减少,同时在Linux和Windows系统上的启动速度更快。这些数据由厂商提供,因此应将其视为参考方向。更低的CPU使用率、内存占用和启动时间意味着服务成本更低、响应更快,但只有通过自身的测试才能确认这一点。如需了解更全面的运行时权衡信息,请参阅我们的Node.js、Deno与Bun的对比分析。
评估Bun 1.4的低风险方法
整体迁移生产系统往往并非明智之举,小型且可逆的实验效果更好。
创建新的 API
搭建项目框架,使用 Bun.serve 构建一个小型服务:
bun init
替换某个图像处理流程
将单个 sharp 处理流程迁移到 Bun.Image,并比较输出质量与处理时间。
迁移某个定时任务
选择一个简单的 cron 作业,用 Bun.cron() 重新实现它。
并行化测试
并行运行现有的测试套件,记录因共享状态而失败的测试:
bun test --parallel
清理依赖项
在分支上尝试安全检查和去重命令,然后查看差异:
bun audit fix
bun dedupe
在 Bun 环境下构建 Next.js 应用
使用 Bun 运行时构建生产版本,并将其与当前的流水线进行对比:
bun --bun next build
无论何种情况,都应实际测量结果,而非依赖已公布的基准数据。
整合趋势
Bun 1.4 的重点不在于新增大量 API,而在于让一个运行时承担原本由多个独立包负责的功能。其整体架构包括:包含 Node.js API 的运行时层、涵盖测试、脚本、安全功能、持续集成及终端工具的工具层,以及用于处理图片、Markdown、浏览器相关功能及定时任务的库层:
Bun 1.4
│
┌─────────┼──────────┐
│ │ │
Runtime Tooling Libraries
│ │ │
Node.js Testing Image
APIs Scripts Markdown
Security Browser
CI Cron
Terminal
npm 生态系统的强大之处在于能够组合数千个小型包,但这种强大也带来了依赖关系复杂、配置繁琐、兼容性问题多、安全更新频繁以及工具分散等弊端。Bun 则采取相反策略:在运行时内部内置实用的基础功能。
核心要点
- 值得探讨的问题已从“Bun 是否比 Node.js 更快?”转变为“我的技术栈中哪些部分可以被 Bun 取代?”
- 内置功能可减少对原生库的依赖,但在替换
sharp或 Playwright 等成熟库之前,请先确认功能一致性。 - 当输入不可信时,务必对
Bun.markdown生成的 HTML 输出进行净化处理。 - 并行运行脚本和测试虽能快速见到成效,但也会暴露出隐藏的顺序问题及共享状态问题。
- 将供应商提供的基准测试视为假设,在最终采用之前需根据自身工作负载验证各项功能。