Bun 都用 AI + Rust 重写了,咋不顺便把 Node.js 的 API 全兼容了?

说白了,兼容简单, 但是性能保证即便用AI也需要时间。

最近 Bun 那边动静挺大------底层从 Zig 换成 Rust,而且这事儿 AI 还帮了不少忙。看到这个新闻,脑子里第一个冒出来的想法就是:

"既然 AI 都能写代码了,让它把 Node.js 的 API 全抄过来不就行了?现在 Node 兼容性不是还有 10% 没搞定吗?AI 搞定它不是分分钟?"

乍一听好像挺有道理的对吧。但你仔细想想就会发现,这剩下的 10%,反而是最难啃的硬骨头。

那些至今没兼容的 Node.js API

咱先摆事实。Bun 官方文档加上社区反馈,下面这些 API 现在还都没法完全跑通,或者行为上对不上:

模块 / API 现在啥情况 卡在哪儿
http 客户端请求体 只支持整块塞进去,不支持流式发送 流式背压那套逻辑是 V8 + libuv 攒出来的,JSC 那边机制不一样
https 的 Agent 配置 部分选项跑出来效果对不上 Agent 复用 Socket 的逻辑跟 Bun 的异步 I/O 调度打架
perf_hooks API 有,但没过 Node 官方测试 性能计时那套语义深度绑在引擎实现上,V8 跟 JSC 路子不同
async_hooks createHook 这些核心 API 还没实现,调用会警告 想完全模拟 V8 的异步追踪就得大改引擎,性能也扛不住
module.register 没实现 Bun 推自己的 Bun.plugin,这个优先级低
原生模块(Native Addons) 像 bcrypt、canvas 这类基本跑不起来 这些模块是按 V8 的二进制编出来的,JSC 用不了
repl 整个模块没动 Bun 自己的 REPL 更强,没必要抄

顺手聊一下 REPL 是啥

上表里的 repl 可能有人不太熟。简单讲,REPL 就是"读一句、跑一句"那种交互式命令行------你打开终端输 node,看到个 > 提示符,那就是 REPL 了。

Node.js 不仅自己带命令行 REPL,还暴露了一个 repl 核心模块,让你能在代码里自己起一个。下面这种用法就是例子:

js 复制代码
// 创建一个自定义 REPL,并注入一个变量
const repl = require('repl');
const r = repl.start('my-app> ');
r.context.greeting = 'Hello from Bun!';

// 运行后,在 REPL 里可以直接使用 greeting 变量
// my-app> greeting
// 'Hello from Bun!'

这个模块能改历史记录、加自动补全、定制输出格式什么的。一些框架(比如 NestJS 那个交互式脚手架)会拿它来在运行时临时开个调试口。

那 Bun 咋就不实现它呢?其实原因挺直接的。Bun 自己就有个更猛的 REPL(直接输 bun 就进),原生支持 TypeScript、JSX、Top-level await,连 npm 包都能自动补全。再说 Node 那个 repl 模块内部挺复杂,牵涉一堆终端控制和事件循环适配,搬到 JSC 上重写不划算。况且真正常用 REPL 的人基本就是开个终端敲一敲,几乎没人会在自己代码里 new 一个 REPL 实例出来。

所以这事儿不是"做不到",是"不值得做"。AI 倒是能帮你把 repl 模块的源码翻译成 Rust,但它不会替你做这个判断------Bun 团队心里清楚得很,自己有个更好的方案,这功能优先级就排到后面去了。这种取舍,AI 替不了。

AI 到底搞不定啥?

你可能会想:"那既然有差异,就想办法兼容呗,AI 写代码这么猛,差哪儿补哪儿不就行了?"

这话听着挺对,但问题在于,AI 能"翻译"代码,没法"适配"行为。下面拿两个具体例子说说。

例子一:流式请求里的"背压"

Node.js 的 http 客户端发大文件的时候,常这么写:fs.createReadStream().pipe(request)。底下走的是 V8 + libuv 的背压机制------TCP 缓冲区满了就自动暂停读,缓冲区空出来再发 'drain' 事件接着读。

想在 JSC 上把这一套原样复刻,得做这些事:自己模拟 libuv 的写缓冲区水位线判断;让 JSC 的异步 I/O 跟 JS 层的 'drain' 事件触发时机对上;处理 stream.write() 返回 false 之后的等待逻辑。

那 AI 能干啥?它确实能把 Node.js 的 _write 实现翻译成 Rust 代码。但翻译完跑起来,背压行为跟 V8 是不是一模一样?AI 验证不了啊------它不知道 JSC 的事件循环啥时候处理 I/O 回调,也不知道微任务队列、定时器精度的差异会怎么影响流控。

Bun 现在的选择就是:先不搞流式发送,干脆把整个请求体缓冲起来。这是个工程上的取舍------真去模拟流式,成本高得离谱,还会拖累平时那些小请求。这种"值不值得"的事儿,AI 拍不了板。

例子二:async_hooks 的异步追踪

Node.js 的 async_hooks 能追踪每个异步资源从创建到销毁的全过程,做类似 CLS(连续本地存储)那种东西就靠它。这套 API 完全是挂在 V8 内部对 Promise、setTimeout、nextTick 的钩子机制上的。

要在 JSC 上弄出一样的语义来,得在 JSC 的每个异步操作入口和出口都插回调,异步 ID 的生成规则、传播路径得跟 V8 严丝合缝,还得控制住性能开销(Node 自己开了这个都会明显变慢)。

AI 能给你写一个看起来能跑的 createHook,但 ID 传播顺序在复杂场景下(比如好几个 Promise 链套着 setImmediate)跟 Node 一不一样,它保证不了;它也不知道 JSC 对 Promise 的优化策略(微任务调度那些)跟 V8 有啥差别,钩子触发时机容易错位。

Bun 一直拖着没实现 async_hooks.createHook,不是写不出来------是写一个行为对得上、性能扛得住的版本,AI 还真搞不定。这得靠真正懂两个引擎内部实现的工程师一行一行去抠。

那 AI 到底干了啥?

话说回来,AI 也没那么废。在 Bun 的开发里,AI 确实有出力:它能根据 Node 的行为描述批量生成边界测试用例,让工程师拿来跟 Bun 的实现对比;也能把 Node 的 TypeScript 类型定义转成 Bun 那边的格式;像 Buffer 里面某些无状态的方法,AI 写起来挺快。

但 "哪些 API 值得兼容"、"性能跟正确性怎么取舍"、"引擎层的差异咋修"------这些事儿还是得人来定。

总结一下

要是 Node.js 和 Bun 跑在同一个引擎上,AI 几乎能把所有 API 一键迁过来。但现实不是这样啊------它俩跑在两套虚拟机上,设计哲学、内部机制全都不一样。

把 V8 的 API 硬搬到 JSC 上,那不叫"翻译",叫"重新设计"。重新设计这事儿,得先搞明白两边的差异,再做取舍,最后还得反复验证------偏偏这些是 AI 最不擅长的。

所以要是你问"AI 是不是早晚都能搞定"------

  • 要是"搞定"是说"写一个看起来能跑的版本",AI 已经能了。
  • 要是"搞定"是说"行为完全对得上、性能不缩水、长期能维护",AI 还差得远。

这也是 Bun 那 10% 没兼容的 API 一直存在的原因。好消息是,对绝大多数人来说,Bun 已经够用了(通过率超 90%,Express、Fastify 这些框架无缝跑)。剩下那 10% 的硬骨头,还是得工程师们一块一块啃------AI 是帮手,不是替身。

相关推荐
menlong9991 小时前
从Prompt狂欢到Agent轨道:20 万行代码真实项目的 AI 工作流实战
前端
huangdong_1 小时前
拼多多商品图片视频批量采集:整店自动分类与高清原图
前端·javascript·音视频
XovH1 小时前
第49篇 k8s之服务网格入门:Istio 简介
后端
胡萝卜术1 小时前
从零开始掌握AI应用开发:我的大模型学习路线图(RAG/Agent/MCP/全栈实践)
前端·javascript·面试
Nightwatchman1 小时前
深入理解内存管理
前端
风骏时光牛马1 小时前
JSON常见踩坑问题与实战避坑案例代码
前端
YAwu111 小时前
从 TodoList 看 React + TypeScript 类型实践
前端·javascript
无毁的湖光Al1 小时前
高可用之路-闲聊监控指标的局限
后端
喵了几个咪1 小时前
基于 Flutter 的 Headless CMS 全平台前端架构:技术解析与二次开发导引
前端·flutter·架构