Bun 源码解析:用 Zig 重写 JavaScript 运行时的极速之路
引言
Bun 是一个用 Zig 语言编写的 JavaScript/TypeScript 运行时,集运行时、打包器、测试框架和包管理器于一体。它的目标很直接:比 Node.js 快,比 npm 快,比 webpack 快——而且是同一个工具。
项目背景
Bun 由 Jarred Sumner 创建,使用 Zig 语言编写,底层使用 JavaScriptCore(Safari 的 JS 引擎)而非 V8。选择 Zig 的原因:手动内存管理带来极致性能,与 C 的无缝互操作,编译时计算减少运行时开销。
核心源码解析
1. JavaScriptCore 集成
与 Node.js 使用 V8 不同,Bun 选择了 JavaScriptCore:
// Bun 的 JS 引擎绑定(简化)
const JSC = @import("javascript_core");
pub fn evaluate(global: *JSC.JSGlobalObject, source: []const u8) !JSC.JSValue {
const result = global.evaluateScript(source);
return result;
}
JSC 的启动速度比 V8 快,内存占用更低,这是 Bun 冷启动快的关键因素之一。
2. 原生打包器
Bun 内置了打包器,直接在 Zig 层面实现模块解析和打包:
pub const Bundler = struct {
resolver: Resolver,
parser: Parser,
linker: Linker,
pub fn bundle(self: *Bundler, entry: []const u8) !BundleResult {
const resolved = try self.resolver.resolve(entry);
const ast = try self.parser.parse(resolved);
return try self.linker.link(ast);
}
};
因为打包器和运行时共享同一个解析器,避免了重复解析的开销。
3. 包管理器
Bun 的包管理器通过并行下载和硬链接实现极速安装:
pub const PackageManager = struct {
// 全局缓存,所有项目共享
global_cache: GlobalCache,
pub fn install(self: *PackageManager) !void {
// 1. 解析依赖树
// 2. 并行下载所有包
// 3. 使用硬链接而非复制,节省磁盘空间
}
};
硬链接策略意味着同一个包在磁盘上只存储一份,所有项目共享。
关键设计模式
总结
Bun 的设计哲学是”一个工具解决所有问题”。通过 Zig 语言的性能优势和全栈集成的架构设计,它在 JavaScript 工具链的每个环节都实现了显著的性能提升。
夜雨聆风