跳到主要内容

Bun Shell、脚本与进程能力

Bun 最先被注意到的,往往是 bun install。但很多脚本仓库和工程工具仓库真正开始认真看它,通常是因为另一层能力:

  • Bun Shell
  • Bun.spawn
  • Bun.spawnSync
  • $ 命令

这部分能力更接近“脚本工程”和“本地工具”。

Bun Shell 是什么

官方文档里提到,Bun Shell 不是单纯去调用 /bin/sh,而是 Bun 自己实现的一套 shell 能力。

这意味着它更适合放在这些场景里看:

  • 本地自动化脚本
  • 构建辅助脚本
  • 发布脚本
  • 开发工作流串联

$ 是最容易先上手的一层

import { $ } from 'bun'

await $`echo "hello bun"`

这类写法在脚本文件里会非常顺,尤其适合取代一些零碎的 shell 命令拼接。

为什么这层值得前端工程师看

因为很多项目里的工程脚本,本来就是这些内容的组合:

  • 删文件
  • 复制文件
  • 跑子命令
  • 处理输出
  • 根据退出码决定下一步

如果这些脚本原来散在:

  • bash
  • Node child_process
  • 一些零碎 CLI

那 Bun Shell 很适合把它们收成一套更统一的写法。

Bun.spawn

官方文档里,Bun.spawn() 用来启动子进程,返回的是 Bun.Subprocess

最基础的例子:

const proc = Bun.spawn(['bun', '--version'])
console.log(await proc.exited)

一个更接近真实脚本的例子

const proc = Bun.spawn(['pnpm', 'lint'], {
stdout: 'pipe',
stderr: 'pipe',
})

const out = await proc.stdout.text()
const err = await proc.stderr.text()
const code = await proc.exited

console.log({ code, out, err })

这种写法很适合:

  • 包装已有 CLI
  • 做工作流脚本
  • 在一个总控脚本里串多个命令

spawnSync

官方文档里也提供了同步版:Bun.spawnSync()

const proc = Bun.spawnSync(['echo', 'hello'])
console.log(proc.stdout.toString())

如果脚本本身是线性的、并且命令不多,这种写法会很直接。

spawn 更适合放在哪些场景里

适合

  • HTTP 服务之外的脚本工具
  • 发布脚本
  • 本地自动化
  • 工程命令编排

要多看一眼

  • 长时间运行的复杂进程树
  • 高度依赖交互终端的脚本
  • 平台兼容要求特别高的工具

stdout / stderr 怎么看

官方文档里,输出流默认是 ReadableStream。这意味着在 Bun 脚本里,可以更自然地去处理子进程输出,而不是把它完全当黑盒。

这在这些场景里很有用:

  • 捕获 lint 输出
  • 读取构建结果
  • 在脚本里做二次判断

交互终端和 PTY

官方 child process 文档还提到,Bun 支持带 PTY 的 terminal 模式。

这更适合:

  • 交互式命令
  • 真正需要 TTY 的脚本
  • 同一终端里连续跑多个命令

这层不是大多数前端项目每天都用,但对工具链脚本会是加分项。

一个更现实的判断

如果项目里已经有很多 Node 工程脚本,例如:

  • 发布版本
  • 生成 changelog
  • 同步子包
  • 批量执行 workspace 命令

那 Bun Shell 和 spawn 系列能力,通常会比 Bun runtime 更早体现价值。

一个更接近真实项目的脚本例子

import { $ } from 'bun'

await $`rm -rf dist`
await $`bun test`

const build = Bun.spawn(['bun', 'build', './src/index.ts', '--outdir', './dist'], {
stdout: 'inherit',
stderr: 'inherit',
})

const code = await build.exited

if (code !== 0) {
throw new Error(`build failed with code ${code}`)
}

这类写法很适合:

  • 本地打包脚本
  • 小型发布流程
  • 代码生成脚本
  • monorepo 里的批处理工具

更适合先记住的主线

对前端工程来说,这一层的重点不是“Bun 也能起进程”,而是:

  • 能不能把工程脚本写得更集中
  • 能不能少一点 bash / Node / CLI 混杂
  • 能不能让构建和发布辅助脚本更统一

参考来源