大家好,我是农村程序员,独立开发者,行业观察员,前端之虎陈随易。我会在这里分享关于 独立开发
、编程技术
、思考感悟
等内容,欢迎关注。
技术群与交朋友请在个人网站联系我,网站 1️⃣:chensuiyi.me,网站 2️⃣:me.yicode.tech。
如果你觉得本文有用,一键三连 (点赞
、评论
、转发
),就是对我最大的支持~
node_modules 隔离

这是本次更新最令人兴奋的功能了,请看上图,左侧是 v1.2.18
的 node_modules 结构,所有依赖都平铺到一起。右侧是 v1.2.19
的 node_modules 结构,在使用 workspaces 管理的 monorepo 多项目仓库可以拥有自己的 node_modules 了。
也就是说,如果你的项目使用了一个依赖的不同版本,那么现在可以多版本共存了。也正是因为这个功能,不少人表示,是时候进入到 Bun 的世界了。
但,这个功能不是默认启用的,使用命令 bun install --linker=isolated
来手动指定安装方式为隔离模式。更好的方法则是在项目根目录创建 bunfig.toml
文件,配置如下:
toml
[install]
linker = "isolated"
这样直接运行 bun install
,无需指定 --linker=isolated
参数。
Bun.sql
速度现在提高了 5 倍
js
import { SQL } from 'bun:sql';
const db = new SQL('postgres://user:pass@host:port/db');
// Bun 自动将这些查询流水线化,
// 将它们发送到服务器,而无需等待每个查询的单独响应。
const queries = [];
for (let i = 0; i < 100; i++) {
// .execute() 用于即发即弃查询
queries.push(db`SELECT ${i}`.execute());
}
// 等待所有结果
const results = await Promise.all(queries);
console.log(results.length); // 100
await db.end();
Bun 的内置 PostgreSQL 客户端 Bun.sql
现在可以自动对查询进行流水线化,从而显著提升性能。
流水线化允许将多个查询发送到服务器,而无需等待前一个查询的响应,从而减少网络延迟的影响。
这在并行执行许多小型独立查询时尤其有效 (例如,一个 API 服务器同时处理多个并发请求)。
此更改默认启用,无需更改代码,在基准测试中,对于高并发工作负载,Bun.sql
现在比在 Bun 中运行的 postgres 包快约 3.4倍
,比在 Node.js 中运行的 postgres 快约 6倍
。
手动选择依赖更新

更新依赖的时候,执行 bun update --interactive
,简写 bun update -i
,即可列出所有待更新依赖,可以手动选择更新哪些依赖。
这个功能跟 npm-check-updates
和 antfu 的 taze
类似,不过能被 bun 内置,还是更方便的。
新增 bun pm pkg
命令
bash
# 获取单个属性
bun pm pkg get name
# 获取多个属性
bun pm pkg get name version
# 设置单个属性
bun pm pkg set name="my-package"
# 设置多个属性
bun pm pkg set scripts.test="jest" version=2.0.0
# 删除单个属性
bun pm pkg delete description
# 删除嵌套属性
bun pm pkg delete scripts.test contributors[0]
虽然好像大部分时候用不上,但也非常实用,有时候需要快速修改属性,就不需要创建单独的脚本文件,或者引入第三方包了。
在 workspaces 中更快的安装速度
修复了导致安装过程中多次重新评估工作区包的错误,这使得使用 Bun 工作区的 Monorepos 的安装速度更快、更可靠。
json
{
"dependencies": {
"react": "18.2.0"
},
"devDependencies": {
"react": "18.3.0"
},
"peerDependencies": {
"react": "18.2.1"
}
}
当多个依赖组都有相同的依赖时,目前已调整解析顺序为 devDependencies
> optionalDependencies
> dependencies
> peerDependencies
。
bun pm pack
增加 --quiet
参数
bun pm pack
命令现在支持 --quiet
参数,使用 --quiet
标志后,它会抑制所有详细输出,仅将生成的 tarball 文件名打印到 stdout。
这对于需要捕获文件名的脚本和自动化工作流程尤其有用。
bash
$ bun pm pack
bun pack v1.2.18
packed 131B package.json
packed 40B index.js
my-package-1.0.0.tgz
Total files: 2
Shasum: f2451d6eb1e818f500a791d9aace80b394258a90
Unpacked size: 171B
Packed size: 249B
👆 这是不加 --quiet
参数的输出。
bash
$ bun pm pack --quiet
> my-package-1.0.0.tgz
👆 这是加上 --quiet
参数的输出。
bash
TARBALL=$(bun pm pack --quiet)
echo "Created: $TARBALL"
> Created: my-package-1.0.0.tgz
👆 具体应用场景和效果如上。
读取 .npmrc
中的 link-workspace-packages
和 save-exact
bun install
和 bun add
现在会读取并应用项目 .npmrc
文件中的 link-workspace-packages
和 save-exact
设置,这允许更精细地控制依赖项管理,与其他包管理器保持一致。
bash
# ./.npmrc
save-exact=true
例如,要始终保存精确版本而不是使用 ^
前缀,可以设置 save-exact=true
。
json
{
"dependencies": {
"is-odd": "3.0.1"
}
}
执行 bun add is-odd
命令,就会在 package.json
中安装固定版本的依赖。
新增 bun why
命令
为了帮助我们调试 node_modules 目录,Bun 现在添加了 bun why <package>
命令,它会跟踪软件包安装的依赖关系链,准确展示该软件包为何成为项目的一部分。
该命令支持使用 glob 模式同时查询多个包,例如 bun why "@types/*"
以及 --depth
和 --top
等标志来控制输出的详细程度。
bash
# See the dependency path to a package
$ bun why react
react@18.2.0
└─ my-app@1.0.0 (requires ^18.0.0)
# Use glob patterns to query multiple packages
$ bun why "@types/*"
@types/react@18.2.15
└─ dev my-app@1.0.0 (requires ^18.0.0)
@types/react-dom@18.2.7
└─ dev my-app@1.0.0 (requires ^18.0.0)
顶级的 catelog
和 catelogs
json
// package.json
{
"name": "my-monorepo",
"workspaces": ["packages/*"],
"catalog": {
"react": "18.2.0"
},
"catalogs": {
"testing": {
"@testing-library/react": "16.0.0"
}
}
}
为了简化配置,bun install
现在支持在根 package.json
的顶层定义依赖项目录。以前,这些字段必须嵌套在 workspaces 对象中,这可能不太直观。现在,可以在根级别声明它们,以实现更清晰的设置。
bun test
与测试资源管理器集成

官方 Bun VS Code 扩展
现在与本机测试资源管理器 UI 集成,bun test
现在可以与扩展通信以报告测试发现、进度和结果。
人工智能代理的紧凑输出

在 Claude Code
等人工智能代理中运行时,bun test
输出更加紧凑,节省了上下文窗口。
test.each
中的 $variable
替换
js
import { test, expect } from 'bun:test';
const testCases = [
{ user: { name: '张三' }, a: 1, b: 2, expected: 3 },
{ user: { name: '李四' }, a: 5, b: 5, expected: 10 }
];
// 以下测试将会生成如下标题
// ✓ 添加 1 和 2 给 张三
// ✓ 添加 5 和 5 给 李四
test.each(testCases)('添加 $a 和 $b 给 $user.name', ({ a, b, expected }) => {
expect(a + b).toBe(expected);
});
Bundler 删除未使用的 Symbol.for()
调用
Input:输入:
js
Sym bol.for("this will be removed");
const a = Symbol.for("this will be kept");
console.log(a);
Output:输出:
js
console.log(Symbol.for('this will be kept'));
Bun 的压缩工具现在能够更智能地消除死代码,使用原始参数 (例如字符串或数字) 对 Symbol.for()
的未使用调用现在已被移除,因为如果生成的符号未被使用,这些调用就不会产生副作用,这可以减小打包文件的大小。
使用 test.coveragePathIgnorePatterns
忽略测试覆盖率报告中的文件
现在,可以使用 bunfig.toml
中新增的 test.coveragePathIgnorePatterns
选项从测试覆盖率报告中排除文件,此功能可用于忽略您不想包含在覆盖率指标中的测试文件、Fixture 或其他非源代码。
该选项接受单个 glob 模式或一个模式数组,路径与这些模式匹配的文件将从生成的覆盖率报告中省略。
toml
[test]
# 可以使用单个键值对
# coveragePathIgnorePatterns = "**/__tests__/**"
# 也可以使用数组模式
coveragePathIgnorePatterns = [
"**/__tests__/**",
"**/test-fixtures.ts",
]
快照文件标题链接已更新
bash
- // Bun Snapshot v1, https://goo.gl/fbAQLP
+ // Bun Snapshot v1, https://bun.sh/docs/test/snapshots
生成的快照文件 (.snap
) 中的标头注释包含一个 goo.gl
链接,这是一个即将弃用的网址缩短服务,此链接已更新为 https://bun.sh/docs/test/snapshots
,以指向 Bun 的官方快照测试文档。
使用 --sql-preconnect
减少首次查询延迟
bash
# 要使用,请设置 DATABASE_URL 并使用标志运行 Bun。
export DATABASE_URL="postgres://user:pass@host:port/db"
# Bun 将在执行 index.js 之前连接到 PostgreSQL。
bun --sql-preconnect index.js
Bun 使用 DATABASE_URL
环境变量来确定连接详细信息,如果预连接尝试失败,应用程序不会崩溃,错误将被妥善处理,并在第一次查询时再次尝试连接。
有了这个功能,就不用费心费力地在代码中处理数据库先连接再使用的问题了,直接从框架层面解决了,牛。
Windows 上经过代码签名的独立可执行文件
bash
bun build ./my-script.ts --compile --outfile my-app.exe
在 Windows 上使用 bun build --compile
创建的独立可执行文件现在支持 Authenticode 代码签名。
此前,Bun 会在可执行文件的末尾附加自定义存档格式,此技术与 Windows 验证代码签名的方式不兼容,因为它会在文件签名后对其进行修改。
为了解决这个问题,Bun 现在将捆绑的源代码和资源嵌入到 PE (可移植可执行文件) 文件中的专用 .bun
部分中,这种方法可以保留可执行文件结构的完整性,允许使用 signtool.exe
等工具对其进行签名,而不会使签名失效。
启动速度提高 1mS,内存占用减少 3MB
Bun 现在启动速度大约快了 1 毫秒,并且占用的 RAM 减少了大约 3MB。
这项改进源自对 Zig 代码库的低级优化,Zig 中 LLVM 后端对生命周期注释的支持不完整,这会导致不必要的 memcpy 操作,从而导致额外的内存页面因页面错误而被放入进程的地址空间。
console-depth=N
配置 console.log
深度
js
// index.js
const nested = {
a: {
b: {
c: {
d: 'I am deeply nested'
}
}
}
};
console.log(nested);
// By default, the output is truncated to a depth of 2.
// $ bun run index.js
// { a: { b: [Object] } }
// Run with `--console-depth=4` to see the full object.
// $ bun --console-depth=4 run index.js
// { a: { b: { c: { d: 'I am deeply nested' } } } }
// Alternatively, configure this in `bunfig.toml`:
// [run]
// console.depth = 4
现在可以配置使用 console.log
记录的对象的检查深度,这对于调试深度嵌套的数据结构非常有用,默认深度仍然为 2 (与 Node.js 匹配
)。
可以在每次运行时使用 --console-depth CLI
标志进行配置,也可以通过 console.depth
设置在 bunfig.toml
中永久配置:
toml
[run]
console.depth = 4
或者使用 --console-depth
CLI 标志:
bash
bun --console-depth=4 index.js
SIMD 加速多行注释解析
js
/*
This is a very, very, very, very, very, very, very, very,
very, very, very, very, very, very, very, very, very,
very, very, very, very, very, very, very, very, very,
very, very, very, very, very, very, very, very, very,
very, very, very, very, very, very, very, very, very,
very, very, very, very, very, very, very, very, very,
very, very, very, very, very, very, very, very, very,
... and so on for many many many thousands of lines ...
very, very, very, very, very, very, very, very, very,
very, very, very, very, very, very, very, very, long
multiline comment.
Bun's lexer now uses SIMD instructions to skip over
this block of text much faster than before.
*/
console.log('This file now parses much faster!');
Bun 的 JavaScript 和 TypeScript 解析器现在使用 SIMD 指令来更快地扫描大型多行注释,这可以显著提高解析超长多行注释的性能。
改进了死 try...catch
块的 tree-shaking
js
// input.js
function test() {
return 'foo';
// 此代码无法访问,将被删除。
try {
return 'bar';
} catch (e) {
console.log(e);
}
}
// bun build --minify ./input.js
// 之前:
function test() {
return 'foo';
try {
return 'bar';
} catch (e) {
console.log(e);
}
}
// 之后:
function test() {
return 'foo';
}
Bun 的打包器现在可以消除 try...catch...finally
代码块,这些代码块属于死代码路径的一部分,例如 return 语句之后的代码块。
这项改进有助于更有效地移除无法访问的代码,从而减少打包文件的大小。
fs.glob
现在支持模式和 exclude 数组
js
import { globSync } from 'node:fs';
import { mkdirSync, writeFileSync } from 'node:fs';
// 创建一些虚拟文件用于演示
mkdirSync('a', { recursive: true });
mkdirSync('b', { recursive: true });
writeFileSync('a/file.js', '');
writeFileSync('a/file.ts', '');
writeFileSync('a/style.css', '');
writeFileSync('b/component.js', '');
// 匹配所有 .js 和 .ts 文件,但排除"b"目录中的任何内容。
const files = globSync(['**/*.js', '**/*.ts'], {
ignore: ['b/**'] // or `exclude`
});
console.log(files.sort());
// => ["a/file.js", "a/file.ts"]
node:fs
模块的 glob
、globSync
和 promises.glob
函数已得到增强,以便与 node-glob
更加紧密地保持一致。
现在,可以将 glob
模式数组作为第一个参数传递,以便同时匹配多个模式。此外,exclude 选项现在接受 glob 模式数组来过滤结果,为现有的基于函数的过滤提供了强大的替代方案。
@types/bun
变得更智能
js
// tsconfig.json
{
"compilerOptions": {
"module": "esnext",
"target": "esnext",
"lib": ["esnext"], // "dom" 未包含
"types": ["bun-types"]
}
}
// index.ts
import type { EventSource as UndiciEventSource } from "undici";
// 此函数需要全局 EventSource 类型
function logEvents(source: EventSource) {
source.onmessage = (event) => {
console.log(event.data);
};
}
// 现在类型检查正确,因为当 DOM 类型未加载时,Bun 的全局 `EventSource`
// 与 `undici` 的 `EventSource` 兼容。
const es: UndiciEventSource = new EventSource("/my-events");
logEvents(es);
此版本修复了 Bun 内置 TypeScript 类型长期存在的一个问题。此前,浏览器和类 Node.js 环境中都存在的全局类型 (例如 EventSource
、Performance
和 BroadcastChannel
) 都是使用类似 interface EventSource {}
空接口声明的。现在,当在 tsconfig.json
中包含 "lib": ["dom"]
时,它们可以与 DOM 的内置类型合并。
但是,如果不包含 DOM 库,这些空接口将与 Node.js 兼容包中的类型冲突。例如,undici 的 EventSource 将与 Bun 的空全局 EventSource 类型不兼容。
Bun 的类型现在更加智能,它会检测你的 tsconfig.json
中是否存在 "lib": ["dom"]
,如果不存在,它会自动从 undici-types
、node:perf_hooks
和 node:worker_threads
等模块扩展相应的 Node.js 兼容类型。这消除了类型错误,并提升了服务器端应用程序的开箱即用体验。
node:module
内置模块中的 SourceMap 类和 findSourceMap() 函数
js
import { SourceMap } from 'node:module';
const payload = {
version: 3,
file: 'output.js',
sources: ['input.js'],
sourcesContent: ['() => {}'],
names: ['add'],
mappings: 'AAAA,SAASA,GAAG'
};
const map = new SourceMap(payload);
//payload getter 返回用于构造 SourceMap 的对象
console.log(map.payload);
// { version: 3, file: 'output.js', ... }
// 查找给定生成位置的原始源位置
const entry = map.findEntry(0, 9);
console.log(entry);
// {
// generatedLine: 0,
// generatedColumn: 9,
// originalLine: 0,
// originalColumn: 9,
// originalSource: 'input.js',
// name: 'add'
// }
Bun 现在实现了 node:module 内置模块中的 SourceMap 类和 findSourceMap() 函数。这允许以编程方式解析、检查和搜索源映射,从而提高了与 Node.js 以及依赖此 API 的工具的兼容性。
此实现还修复了解析包含 names 字段的源映射的错误,并解决了源映射解析失败时可能出现的内存泄漏。
现在支持 process.features.typescript
js
console.log(process.features.typescript);
// "transform"
console.log(process.features.require_module);
// true
console.log(process.features.openssl_is_boringssl);
// true
为了提高与 Node.js 的兼容性,现已实现 process.features.typescript
。此属性返回字符串 transform
,反映 Bun 的运行时默认转译 TypeScript。此外,现已支持 process.features.require_module
和 process.features.openssl_is_boringssl
。
os.networkInterfaces()
现在可以正确返回 scopeid
js
import { networkInterfaces } from 'os';
const interfaces = networkInterfaces();
for (const name of Object.keys(interfaces)) {
for (const net of interfaces[name]) {
// 对于 IPv6,`scopeid` 属性现在已正确命名。
if (net.family === 'IPv6') {
console.log(net.scopeid);
// => 0 (or another number)
console.log(net.scope_id);
// => undefined
}
}
}
os.networkInterfaces()
中有一个错误已被修复,该错误导致 IPv6 网络接口返回 scope_id 属性,为了提高与 Node.js 的兼容性,此属性已重命名为 scopeid。
现已支持 vm.constants.DONT_CONTEXTIFY
js
import { createContext, isContext, constants } from 'node:vm';
const sandbox = { a: 1 };
const context = createContext(sandbox, {
// 使用新常量来防止沙盒对象上下文化
[constants.DONT_CONTEXTIFY]: true
});
// 原始沙盒对象不是上下文
console.log(`Is sandbox a context? ${isContext(sandbox)}`); // "沙盒是一个上下文吗?false"
// 返回的对象是实际的上下文
console.log(`Is context a context? ${isContext(context)}`); // "上下文是上下文吗?是的"
// 沙盒和上下文不是同一个对象
console.log(`Are they the same? ${sandbox === context}`); // "它们相同吗?false"
node:vm
模块现在支持 vm.constants.DONT_CONTEXTIFY
,创建新的 vm.Context
时,可以将此符号作为选项传递,以防止 sandbox 对象被 上下文化
。
在此模式下,sandbox 对象本身未链接到虚拟机的上下文,并且 vm.isContext(sandbox)
将返回 false。这提高了与 Node.js 的兼容性,并提供了对虚拟机环境更细粒度的控制。此更改还提高了 vm 模块中动态 import()
的可靠性。
v8C++API 改进
js
// 使用 V8 C++ API 创建或修改数组的本机插件。
import { processArray } from 'some-native-addon';
// 如果原生插件使用新实现的 V8 API 函数,现在 Bun 中即可正常运行。
const result = processArray([10, 20, 30]);
console.log(result);
Bun 对 V8 C++ API
的实现进行了显著改进,允许原生 Node.js 插件在 Bun 中运行。
此版本新增了对多个用于与数组和对象交互的核心函数的支持,包括 v8::Array::New
、v8::Object::Get
、v8::Object::Set
和 v8::Value::StrictEquals
。
这使得 Bun 的 API 更接近与 Node.js v24
的完全 ABI 兼容性,这意味着更多的原生模块将可以开箱即用,而无需重新编译。