Agent Developer Roadmap
JavaScript 运行时

JavaScript 运行时:从模块入口到宿主边界

核验日期:2026-07-16。版本观察窗口为 Node.js 26 Current、24/22 LTS,Deno 2.9,Bun 1.3,以及 Cloudflare Workers 在当前 compatibility date 下的运行时。版本、配额和兼容性会变化,生产决策必须重新核对各文末官方来源。

JavaScript 语法不能独自读取文件、监听端口或启动线程。引擎负责解析、优化和执行 ECMAScript;运行时把引擎、事件循环、模块加载器、系统调用、网络栈、安全边界和诊断工具装配成可部署的宿主。这里沿同一条请求链比较 Node.js、Deno、Bun 和 Edge Runtime:入口怎样解析,依赖怎样加载,异步工作怎样调度,数据怎样跨越 JavaScript 与宿主,权限在哪里判断,结果怎样被观察和恢复。

在路线中的职责

构建工具阶段回答“源码怎样变成可交付产物”;这里继续解释“产物到了一个宿主后怎样被解析、执行并访问外界”;全栈后端阶段再基于这些事实设计请求、状态和持久化。构建 target: node 只会改变产物假设,不会自动赋予文件权限,也不会保证一个 Node 包能在 Bun、Deno 或 Worker 中运行。使用标准 RequestResponseURLReadableStream 的业务核心通常更容易迁移,但服务监听、文件、进程、原生扩展、环境变量和可观测性仍是宿主专属边界。

这条链也给出故障排查顺序。ERR_MODULE_NOT_FOUND 先属于解析与包边界;请求偶发长尾要区分事件循环阻塞、线程池拥塞与上游等待;PermissionDenied 或 Worker 资源限制属于宿主策略;返回成功后数据仍丢失,则要检查生命周期和持久化边界,而不是先更换 JavaScript 引擎。

目标读者与完成条件

读者已经理解执行栈、Promise、ESM、CommonJS 与基本 HTTP。完成这一阶段后,应能用证据回答以下问题:

  • 引擎、运行时、包管理器、构建器与部署平台分别拥有哪一步,为什么“都能执行 TypeScript”不代表语义相同。
  • Node.js 的 V8、libuv、事件循环阶段、线程池、ESM/CJS 和 LTS 策略怎样共同决定应用行为。
  • Deno 的默认拒绝、细粒度权限、Web API、npm/Node 兼容层和一体化工具链怎样影响迁移与供应链边界。
  • Bun 的 JavaScriptCore、Zig 宿主、内置转译/包管理/测试/打包能力与 Node 兼容目标之间有哪些收益和缺口。
  • Edge Runtime 的 Isolate、请求作用域、分布式实例、CPU/内存/子请求配额、平台绑定和 compatibility date 为什么改变传统服务器假设。
  • 怎样在没有营销跑分的情况下,用同一契约验证正确性、模块兼容、权限、启动、吞吐、尾延迟、资源与恢复。

学习主线

先看输入如何成为可执行模块。文件路径、URL、裸包名、exports 与条件导出会经过不同解析规则;一个包能安装,不代表它在目标运行时选中了正确入口,也不代表原生扩展可以加载。排查时要保存真实解析结果、模块格式、缓存状态和首个错误。

模块加载后,再看 JavaScript 与宿主怎样协作。同步栈、microtask、timer、I/O callback、线程池、Worker 和平台调度共同决定任务何时推进;文件、网络、流、进程与 FFI 则跨越宿主边界。时序代码、event-loop delay、CPU profile、资源句柄和 backpressure 记录,比“异步所以不会阻塞”这类概括更可靠。

权限、生命周期和发布决定同一份代码能否安全运行。Deno 的显式权限、Node 的进程能力、Bun 的兼容层和 Workers 的 Isolate/配额解决的是不同问题;它们都不能代替输入验证和多租户隔离。启动、信号、后台任务、驱逐与优雅关闭还会改变状态保存和请求重试方式。

最后才比较性能。固定版本、机器或区域、CPU/内存限制、依赖、缓存状态、连接复用、数据量和并发,记录启动、p95/p99、错误率、CPU、内存与原始样本。厂商跑分可以提供实验线索,不能直接替代项目测量。

这一部分不重复 ECMAScript 入门、完整打包流程和数据库事务。运行时即时转译只讲 loader 与宿主行为;数据库、身份和业务工作流分别在后端与 Agent 部分展开。Node/Deno/Bun 的文件能力与 Workers 的 KV、D1、R2、Durable Objects 也不会被硬凑成同一种 API。

文章与建议顺序

文件核心问题建议产出
nodejs.md成熟的进程型运行时怎样把 V8、libuv、模块与 LTS 生态组织起来能定位事件循环阻塞、线程池拥塞、模块边界和退出问题
deno.md默认拒绝和 Web 标准优先怎样与 npm/Node 兼容共存能写最小权限命令并评估现有 Node 项目迁移
bun.md一体化原生工具链和 JavaScriptCore 怎样改变启动、兼容与维护成本能区分包管理器替换、测试器替换和运行时替换
edge-runtime.mdIsolate 和分布式请求执行怎样改变进程、状态、延迟与配额假设能判断哪些逻辑适合边缘,哪些必须留在区域服务
comparison.md在相同契约与场景下怎样选择而不是按单项跑分投票形成带约束、证据、回滚门槛的决策记录
summary.md怎样把运行时知识交接给全栈后端阶段留下模块、权限、生命周期、资源和可观测性记录

第一次学习建议按表格顺序阅读:Node.js 给出最完整的传统服务器模型;Deno 与 Bun 分别改变安全默认值和工具链边界;Edge Runtime 再改变进程与部署假设。已有生产经验的读者可先读横向比较,选一个与当前事故最接近的文章回查。

贯穿项目:同契约多运行时读取服务

贯穿示例只实现读取,不提前进入数据库写入、认证、队列或框架路由。输入是仓库共享的 examples/contracts/technologies.json,对外契约保持:

  • GET /health 返回运行时名称、版本和进程/实例可用信息,不泄露主机与 secret。
  • GET /technologies 可用 ?query= 做大小写不敏感过滤,成功返回 JSON 数组。
  • 不支持的方法返回 405 并带 Allow: GET;不存在的路径返回结构化 404
  • 请求使用 x-request-id 关联日志;若调用方未提供则生成新值,并回写响应头。
  • 读取、解析或平台绑定失败时返回稳定错误码,日志记录内部原因,响应不暴露绝对路径和堆栈。

共享核心可以接收普通对象数组并返回普通对象数组,避免把 fsDeno.*Bun.* 或平台 binding 渗入领域函数。适配层必须保持显式,因为“读取文件”在 Node/Deno/Bun 是本地 I/O,在 Worker 中通常应改为构建时静态导入、KV/R2/D1 或环境 binding。强行制造一个万能文件系统接口只会隐藏真实部署差异。

统一观察方法

同一服务在四个宿主中都通过功能契约后,再比较性能与运维。每次实验至少记录:运行时精确版本、操作系统/区域、CPU 与内存限制、依赖锁文件、冷/热定义、并发、连接复用、数据大小、预热次数、采样次数、p50/p95/p99、错误率、CPU/内存和原始结果。Edge 还要记录 compatibility date、套餐与平台绑定;本地运行时要记录容器基础镜像、架构和 cgroup 限制。

观察面最小实验不能推出的结论
启动进程/实例从启动到健康检查成功,区分镜像拉取和应用初始化Hello World 启动快不等于大型应用尾延迟低
模块冷缓存加载依赖、热缓存重复运行、ESM/CJS/条件导出 fixture单个包能导入不等于整个 npm 生态兼容
I/O固定响应体、连接复用、流式大响应、慢客户端单机 loopback 吞吐不等于公网端到端体验
CPU固定纯计算并分别在主线程、worker/平台允许方式运行引擎微基准不等于混合业务成本
内存稳态 heap、峰值 RSS/Isolate、GC pause、泄漏趋势一次采样不能证明无泄漏
安全默认启动、最小允许、明确拒绝、依赖安装脚本权限开关不能替代输入验证与隔离设计
恢复SIGTERM/驱逐、在途请求、重试、幂等、重新启动“服务自动拉起”不证明请求没有重复副作用

统一故障证据卡

每次排障先保存一张证据卡,而不是立刻清缓存或切运行时:

  1. 请求或命令:入口文件、参数、cwd、URL、method、request id。
  2. 版本与平台:runtime、engine、OS/region、架构、compatibility date、依赖锁提交。
  3. 模块边界:失败 specifier、importer、解析条件、模块格式、缓存状态。
  4. 权限与配额:允许/拒绝参数、CPU、内存、连接、子请求、文件路径与环境变量范围。
  5. 时序:开始、排队、I/O 等待、CPU、响应、后台任务与退出时间。
  6. 现象:首个错误、错误码、调用栈、profile/trace、返回给用户的安全错误。
  7. 恢复:是否可重试、是否幂等、在途请求怎样处理、怎样回滚版本或 compatibility date。

证据卡的作用是找到第一个错误中间状态。例如应用在 Node 正常、Bun 失败,先比较解析结果和具体 Node API,不先把全部依赖升级;Worker 本地开发正常、线上失败,先比较 compatibility date、binding、资源限制与区域网络,不先把业务函数改写。

版本策略

Node.js 生产环境优先使用受支持 LTS;截至核验日,v24 与 v22 为 LTS,v26 为 Current,v20 已结束生命周期。Node 项目从 v22/24 迁移到 v26 前应先看依赖原生扩展、弃用警告、权限模型和 loader 行为。Deno 2.x 与 Bun 1.x 都在快速补齐 Node 兼容性,minor/patch 可能显著改变可运行包集合,因此 lock runtime 版本、保存兼容 fixture 比“支持 Deno 2/Bun 1”这类宽泛声明更可靠。Cloudflare Workers 通过 compatibility date 把运行时行为变化变为显式选择;升级日期本身就是代码变更,需要 staging、回归与回滚记录。

学习与验收路径

每篇文章都遵循同一验证节奏,但目录按技术自身模型展开:

  1. 先画出引擎、事件循环、宿主 API、工具链和部署平台的所有权。
  2. 用最小入口观察模块识别、解析和缓存,不用 bundler 掩盖问题。
  3. 实现 HTTP 读取示例,显式处理 URL、取消、流、错误和 request id。
  4. 加入一个 CPU 阻塞和一个慢 I/O 故障,使用运行时原生诊断入口定位。
  5. 收紧权限或配额,验证拒绝路径和安全响应。
  6. 模拟进程终止或实例驱逐,确认在途读取、后台工作和重试语义。
  7. 最后才运行同条件 benchmark,保留原始样本并解释适用范围。

会运行四条命令还不足以通过本阶段。你需要完成一次有证据的选择:写明需求与信任边界,排除不满足硬约束的候选,对剩余候选按可靠性、兼容性、性能、使用难度、维护成本和适用规模比较,并留下回滚路径。

官方资料入口

本页只建立导航和验收坐标。机制、错误和版本结论分别在文章中展开,并在 comparison.md 汇总选型,在 summary.md 形成进入全栈后端栏的交接包。

返回在线文档首页

在 GitHub 上编辑此页

本页目录