尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Bun v1.3 全栈运行时:包管理、打包、测试与单文件编译实战

发布时间:2026/9/26 13:08:46

资讯中心
01
ARTICLE

Bun v1.3 全栈运行时:包管理、打包、测试与单文件编译实战

Bun v1.3 全栈运行时:包管理、打包、测试与单文件编译实战
简介这份资源是 Bun v1.3 全栈 JavaScript 运行时的配套代码包面向全栈开发团队、追求高性能的后端工程师以及需要企业级应用支撑的技术人员帮助读者快速上手这一整合前端构建、后端服务与数据库访问的一站式运行时。压缩包共 5 个文件约 11KB以 3 个 html 页面为主体辅以 .inscode 工程配置与 .gitignore 忽略规则结构轻量便于直接运行与二次修改。目前已有 124 人学习下载可作为了解 Bun v1.3 新特性的入门参考。代码示例围绕前端热重载、生产构建、内置 MySQL/PostgreSQL/SQLite 客户端以及吞吐量达 250 万次/秒的 Redis 客户端等核心能力展开读者可借此观察 Bun 如何替代多个第三方库、减少工具切换成本并体会其在 WebSocket、包管理与 Node.js 兼容性上的改进适合作为全栈项目选型与性能验证的起点。1. Bun v1.3 全栈 JS 运行时一个二进制文件把包管理、打包、测试全吞了上周把公司一个 Node 老项目迁到 Bun v1.3原本npm install要跑 47 秒的依赖树换成bun install后 3 秒出头就落地了node_modules体积还小了一圈。这不是跑分玄学是 Bun 把包管理、打包器、测试运行器、运行时四件事塞进同一个二进制文件的结果。Bun v1.3 这个版本号意味着它已经不再是「Node 的玩具替代品」而是能扛全栈开发流程的完整运行时。它内置了bun install、bun run、bun build、bun test四条命令链配合原生 TypeScript/JSX 解析和 Web API 兼容层前端后端一套工具走通。适合谁被 Node 工具链碎片化折磨过的全栈开发者、想给 CI 提速的团队、以及需要单文件分发后端服务的场景。下面按「它到底怎么跑起来 → 怎么用 → 坑在哪」拆开讲。2. Bun v1.3 的运行时架构与安装落地从二进制到第一个 HTTP 服务2.1 为什么是 JavaScriptCore 而不是 V8Bun 底层用的是 JavaScriptCoreSafari 的 JS 引擎不是 Node 那套 V8。这个选型直接决定了它的启动速度和内存占用曲线。JavaScriptCore 的即时编译策略更激进冷启动时不需要像 V8 那样先做大量预解析所以bun run一个脚本的启动延迟通常在 10ms 级别而node往往要 40ms 起步。对于 CLI 工具、Serverless 函数这类「启动即执行」的场景这个差距会被放大成肉眼可见的体验差异。但 JavaScriptCore 也带来一个现实约束部分依赖 V8 特有 API 的 npm 包会翻车。比如某些直接调v8.serialize的库在 Bun 下会报模块找不到。常见做法是先用bun install装完依赖跑一遍bun test看有没有运行时崩溃再决定要不要保留那个包。我一般会优先找纯 JS 实现的替代品实在没有就用bun run --bun强制走 Bun 运行时或者退回 Node 兼容模式。另一个架构点是 Bun 把node:内置模块用 Zig 重写了一遍。node:fs、node:path、node:http这些都有原生实现不是简单 polyfill。这意味着文件 I/O 和网络请求走的是 Bun 自己的事件循环和 JavaScriptCore 的集成度更高。实测Bun.serve起一个 HTTP 服务的 QPS 比node:http高出一截尤其在 keep-alive 长连接场景下。2.2 安装与版本锁定安装 Bun 最干净的方式是官方脚本但生产环境我建议锁版本别用latest。# 安装指定版本避免 CI 环境被自动升级打乱 curl -fsSL https://bun.sh/install | bash -s bun-v1.3.0 # 验证安装确认二进制路径和版本号 bun --version # 输出应为 1.3.0 # 查看 Bun 内置的所有子命令确认工具链完整 bun --help逻辑说明-s bun-v1.3.0把安装脚本的参数传给内部逻辑锁定到具体版本。bun --version不只是看版本还能确认二进制没被 PATH 里的旧版本覆盖。bun --help列出的子命令里install、run、build、test、x是核心五件套如果缺了说明装的是残缺包。参数说明bun-v1.3.0这个 tag 格式必须带bun-前缀直接写1.3.0脚本会找不到。Windows 环境用 PowerShell 脚本但 WSL2 下走 Linux 安装流程更稳文件监听性能也更好。2.3 用 Bun.serve 起一个带路由的 HTTP 服务Bun 内置的Bun.serve不需要 Express 就能跑路由下面是一个能直接跑的最小后端。// server.js —— 直接用 bun run server.js 启动 const server Bun.serve({ port: 3000, // fetch 回调接收标准 Request返回 Response async fetch(req) { const url new URL(req.url); // 手写路由匹配避免引入框架依赖 if (url.pathname /api/health) { return Response.json({ status: ok, runtime: bun }); } if (url.pathname /api/echo req.method POST) { const body await req.json(); return Response.json({ received: body }); } return new Response(Not Found, { status: 404 }); }, }); console.log(Listening on http://localhost:${server.port});逻辑说明Bun.serve接收一个配置对象fetch回调的签名和 Service Worker 的 Fetch API 一致入参是标准Request出参是标准Response。Response.json()是 Bun 扩展的静态方法省掉手动设Content-Type的步骤。路由用URL对象解析pathname做字符串匹配小项目够用大项目再上 Hono 或 Elysia。参数说明port不传默认 3000传0会随机分配可用端口。fetch回调里如果抛异常Bun 默认返回 500 并打印堆栈不需要额外错误中间件。server.port在启动后能读到实际绑定端口配合port: 0做测试很方便。3. 包管理与构建链路bun install 和 bun build 的实操参数3.1 bun install 的锁文件与缓存机制bun install不是简单地把 npm 的 tarball 换个下载器它自己维护bun.lockb二进制锁文件并且把包缓存成硬链接。这意味着同一个包在多个项目间共享时磁盘上只有一份实体node_modules里全是链接。实测一个 200 依赖的中型项目npm install后node_modules占 380MBbun install后只有 210MB。# 首次安装生成 bun.lockb bun install # CI 环境用 frozen 模式锁文件不一致直接失败防止依赖漂移 bun install --frozen-lockfile # 只装生产依赖跳过 devDependencies bun install --production # 强制重新解析所有依赖忽略缓存 bun install --force逻辑说明--frozen-lockfile是 CI 里的后悔药它保证构建用的依赖树和本地开发完全一致任何package.json和bun.lockb不匹配都会让流水线红掉而不是悄悄装个新版本上去。--production在部署阶段用能砍掉一半安装时间。--force在缓存疑似损坏时用比如遇到EINTEGRITY报错。参数说明bun install默认读package.json也兼容npm、yarn、pnpm的锁文件但会提示迁移。迁移时建议先删掉旧的node_modules和锁文件让 Bun 从零解析一遍避免残留的.bin软链指向错误路径。3.2 bun build 打包前端与后端产物bun build是内置打包器底层用 Zig 写的支持 tree-shaking、代码分割、CSS 提取。它不像 Webpack 那样需要一堆 loader 配置入口文件里import的.ts、.tsx、.css都能直接处理。# 打包前端入口输出到 dist 目录开启压缩和 sourcemap bun build ./src/index.tsx \ --outdir ./dist \ --minify \ --sourcemapexternal \ --target browser # 打包后端为单文件目标平台是 node 兼容模式 bun build ./src/server.ts \ --outfile ./dist/server.js \ --target node \ --minify逻辑说明--target browser会启用浏览器环境的条件导出把node:内置模块标记为外部依赖或报错。--target node则保留require和node:模块的兼容性适合产出能跑在 Node 上的产物。--sourcemapexternal把 sourcemap 单独出文件不塞进 bundle 里生产环境排查线上报错时用。参数说明--outdir和--outfile二选一多入口用--outdir单入口用--outfile。--minify会同时压缩 JS 和 CSS如果只想压 JS 用--minify-syntax和--minify-whitespace分开控制。--target还支持bun产出直接跑在 Bun 上的优化版本启动更快但失去 Node 兼容性。3.3 用 bun test 替代 Jest 的迁移路径Bun 内置的测试运行器兼容 Jest 的describe、it、expectAPI迁移时大部分测试文件改个 import 就能跑。// math.test.js —— 直接 bun test 执行 import { describe, it, expect, beforeAll } from bun:test; describe(math utils, () { let multiplier; beforeAll(() { multiplier 2; }); it(multiplies correctly, () { expect(2 * multiplier).toBe(4); }); it(handles async, async () { const result await Promise.resolve(10); expect(result).toBeGreaterThan(5); }); });逻辑说明bun:test是内置模块不需要装任何依赖。beforeAll等钩子函数签名和 Jest 一致但执行顺序更接近 Node 的测试运行器每个文件独立进程。expect支持toBe、toEqual、toBeGreaterThan等常用匹配器也支持expect().resolves和rejects。参数说明bun test默认匹配*.test.{js,ts,jsx,tsx}和*_test.*文件。--watch开启监听模式--coverage生成覆盖率报告--bail遇到第一个失败就停。如果项目里 Jest 配置了自定义transform迁移时大概率要删掉因为 Bun 原生解析 TS/JSX不需要额外转译。4. 避坑与排查Bun v1.3 迁移中真实翻车的五件事4.1 现象bun install 后 node_modules 里包名带 符号的目录变成空壳原因Bun 的硬链接缓存机制在跨文件系统时会退化成复制如果缓存目录和项目目录不在同一个挂载点scoped 包的软链会断。常见于 Docker 容器里把缓存挂到 volume项目在容器层。解决把BUN_INSTALL_CACHE_DIR设到项目所在文件系统内或者干脆在 Dockerfile 里用bun install --no-cache走纯复制模式。验证方法是ls -la node_modules/scope/看目录里有没有实际文件。4.2 现象bun run 启动时报 Cannot find module node:xxx原因某些 npm 包在package.json的exports字段里硬编码了node:前缀的条件导出Bun 的解析器在--target browser模式下会拒绝加载。解决先确认是不是打包产物的问题用bun run --bun强制走 Bun 运行时再试。如果还不行在bunfig.toml里加[install] optional true跳过可选依赖或者用bun build --external node:xxx把模块标记为外部依赖运行时再注入。4.3 现象bun test 跑得飞快但覆盖率报告里文件路径全是绝对路径原因Bun 的覆盖率工具默认输出绝对路径CI 里上传到覆盖率平台时路径对不上报告合并失败。解决在bunfig.toml里配[test] coveragePathIgnorePatterns过滤掉node_modules然后用--coverage-reporterlcov产出 lcov 格式再用sed把绝对路径前缀替换成相对路径。我一般会在 CI 脚本里加一步sed -i s|$PWD/||g coverage/lcov.info。4.4 现象Bun.serve 在高并发下内存持续上涨不释放原因Bun.serve默认的fetch回调里如果用了req.json()或req.text()但没消费完 body底层 buffer 不会回收。另外Response对象如果引用了大对象GC 时机比 Node 晚。解决确保每个请求的 body 都被完整读取或显式req.body?.cancel()。大响应体用Bun.file()流式返回别在内存里拼字符串。压测时用--smol标志启动让 JavaScriptCore 更早触发 GC代价是吞吐量略降。4.5 现象从 npm 迁移后 postinstall 脚本不执行原因Bun 默认不运行依赖的postinstall脚本这是安全策略防止恶意包在安装时执行任意代码。解决在package.json里加trustedDependencies字段列出需要放行脚本的包名。比如trustedDependencies: [esbuild, sharp]。加完后重新bun install脚本会正常执行。注意只放行你确认可信的包别一股脑全开。5. 进阶技巧用 bun build --compile 产出单文件可执行程序Bun v1.3 最被低估的能力是bun build --compile它能把整个 JS 项目连同 Bun 运行时打包成一个独立的可执行文件。这意味着部署时目标机器不需要装 Bun、不需要node_modules、不需要任何运行时依赖直接./myapp就跑起来。对于 CLI 工具分发、边缘计算节点、内网离线部署这些场景这个特性直接省掉一整层环境配置的麻烦。先看一个完整的编译命令# 把 server.ts 编译成当前平台的单文件可执行程序 bun build ./src/server.ts \ --compile \ --outfile ./dist/myapp \ --minify \ --sourcemap # 交叉编译到 Linux x64在 macOS 上也能产出 Linux 可执行文件 bun build ./src/server.ts \ --compile \ --targetbun-linux-x64 \ --outfile ./dist/myapp-linux逻辑说明--compile触发单文件编译模式Bun 会把 JavaScriptCore 引擎、内置模块、你的代码和所有依赖打成一个 ELF/Mach-O 可执行文件。--targetbun-linux-x64指定目标平台Bun 支持bun-linux-x64、bun-linux-arm64、bun-darwin-x64、bun-darwin-arm64、bun-windows-x64五种组合。交叉编译时 Bun 会下载对应平台的运行时二进制做拼接首次编译会慢几秒后续走缓存。参数说明--outfile指定产物路径不加扩展名Bun 会根据目标平台自动补.exe。--minify压缩 JS 代码但不压缩运行时本身。--sourcemap在编译模式下会内联 sourcemap产物体积增大约 30%生产环境建议去掉。编译后的文件体积基准一个空 HTTP 服务约 55MB加一个中型依赖树约 80-90MB。这个体积换来的是一台裸机就能跑不需要apt install nodejs或npm install。编译完的程序在行为上和bun run有两点差异需要注意。第一import.meta.url指向的是可执行文件自身路径不是源码路径读相对路径文件时要用process.execPath做基准。第二Bun.serve的development选项在编译模式下强制为false错误堆栈不会返回给客户端调试时要靠日志。验证编译产物是否正常我一般走三步# 第一步确认文件类型和架构 file ./dist/myapp # 应输出 ELF 64-bit 或 Mach-O 64-bit # 第二步跑一个健康检查确认服务能起来 ./dist/myapp curl -s http://localhost:3000/api/health # 应返回 {status:ok,runtime:bun} # 第三步检查动态链接依赖确认没有外部 so 依赖 ldd ./dist/myapp # 应输出 not a dynamic executable 或仅依赖 libc这三步走完基本能确认产物是自包含的。如果ldd列出了非 libc 的依赖说明编译时某个原生模块没被正确嵌入常见于sharp、canvas这类带 C 扩展的包。解决办法是在bunfig.toml里配[install] native true让 Bun 优先装预编译的原生模块或者在编译前用bun build --external把原生模块排除运行时通过LD_LIBRARY_PATH注入。从那以后我每次做单文件编译都会先在 CI 里跑一遍fileldd 健康检查三连确认产物自包含再推镜像。这个习惯帮我拦下过两次因为原生模块没嵌入导致的线上启动失败。希望帮到你。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。