“还在用 Node.js那玩意儿不是过气了吗”这句话我这两年在技术圈听了不下几十次。说这话的人往往左手刚用npm create vite初始化了一个前端工程右手刚在某个后台管理系统里点击了一个依赖 Node.js 工具链构建出来的按钮。挺魔幻的但这就是现状一个技术一旦不再天天上热搜就会有人觉得它“死了”。我自己是从 Node.js 0.10 时代一路用过来的从 Express 写接口、Webpack 打包到后来用 Egg.js 做中台、用 Next.js 做 SSR再到现在维护着一批跑在 Node 22 LTS 上的线上服务。这篇文章不打算唱赞歌也不打算贩卖焦虑就想把一件事讲清楚Node.js 到底是不是真的“过气”了如果没过气它凭什么在 Deno、Bun 这些新运行时轮番轰炸下依然占据着大量生产环境顺便把大家最近高频踩坑的几个 Node.js 安装和版本问题一起说说。1. “Node.js过气”的错觉从哪来热度、竞争者与大版本的稳定期1.1 新运行时带来的冲击波Deno 和 Bun 抢走了话题2018 年 Ryan DahlNode.js 之父发布 Deno当时整个技术社区都在沸腾。他公开承认 Node.js 早期设计里有一堆他后悔的地方比如没有原生 TypeScript 支持、包管理机制混乱、权限模型太粗放。紧接着 2022 年 Bun 横空出世主打一个“比 Node 快好几倍”安装依赖快、启动快、内置打包器直接把 Node 的痛点按在地上摩擦。更别提这三四年里 Rust、Go 在云原生领域如日中天大家都在讨论用 Go 写网关、用 Rust 写高性能中间件。一个客观事实是在“新东西层出不穷”的技术市场里Node.js 确实不再站在话题中心。但它和“过气”是两码事。技术圈一直有个毛病——把“话题热度”和“生产价值”画等号。Reddit 上有人说一句“Node.js sucks”能收获几百个赞但这改变不了全球数百万台服务器上跑着 Node 进程的事实。1.2 前端框架迭代带来的错觉你每天用的工具其实都是 Node另一个制造“过气”错觉的原因是前端框架的迭代速度。React、Vue、Vite、Tailwind、各种全栈框架一年到头热搜不断而 Node.js 只是它们背后的“引擎”。大家讨论 Vite 快不快的时候很少有人会顺嘴提一句“Vite 本身是用 Node.js 写的”。这种心态有点像你每天用着安卓手机却觉得“安卓系统是不是过气了因为大家现在都在聊 AI”。工具链越是稳定越不容易被讨论但它恰恰是那个被依赖最多的地基。我经常跟团队里的小朋友说你现在敲的每一行前端代码几乎都要经过 Node.js 转译、打包、检查、压缩你以为你在和 Node 无关的技术打交道其实你已经被 Node 包围了。1.3 热度数据的另一面下载量和生产占比不会说谎如果只看技术论坛的热帖你确实会以为 Node.js 快不行了。但打开数据看看呢npm 每周的下载量依然是全球最大的包分发生态没有之一。GitHub 上依赖 npm 的项目数量、云厂商对 Node 运行时的支持成熟度、全球范围内 Node 相关岗位的招聘数量全都摆在那里。还有一个更加现实的原因Node.js 进入了 LTS 稳定期之后API 变动幅度很小。一个框架如果天天搞 Breaking Change话题热度反而高——因为大家都在骂它。Node.js 现在像 Linux 一样不刷存在感但处处都在。稳定对于一个生产环境运行时来说就是最大的竞争力。2. 回到根本非阻塞I/O与事件循环Node.js真正值钱的地方2.1 一句话说清楚 Node.js 是什么在深入“为什么还在用”之前先给刚接触的朋友补个基础概念。Node.js 本质上是一个基于 Chrome V8 引擎的 JavaScript 运行时它让 JavaScript 可以脱离浏览器、跑在服务器上。你能用它写后端接口、写命令行工具、写桌面应用、写各种自动化脚本。那它和传统的后端技术比如 Java、PHP核心差异在哪答案就是四个字非阻塞。Node.js 采用事件驱动架构配合单线程的事件循环Event Loop让一个进程可以同时处理海量的并发连接。2.2 用一个餐厅例子理解事件循环我一直觉得当年学事件循环最好的类比就是餐厅点餐传统的多线程服务器就像一个大餐厅每个客人来了餐厅就派一个专职服务员全程陪同点菜、等菜、上菜、结账这个服务员被这个客人完全占用着。客人一多服务员就不够用了——这就是“一个连接一个线程”的模型线程切换和资源开销都非常大。Node.js 的做法则相反整个餐厅只有一个非常勤快的服务员单线程。客人点完菜之后服务员不会站在那里等厨房出菜而是立刻去接待下一位客人。等厨房把菜做好了喊一声“宫保鸡丁好了”服务员再端着菜去送给对应桌的客人。这个“厨房喊一声、服务员再去端”的机制就是事件循环的核心。这个设计有两个关键点第一等待 I/O 的时候不占用任何线程资源第二回调完成后会重新回到主线程执行。对于 Web 服务这种“大部分时间都在等数据库查询、等文件读取、等上游 API 响应”的场景Node.js 的性能表现非常亮眼。一个 Node 进程扛住上万并发连接在硬件资源并不夸张的情况下是可以做到的。2.3 为什么有些场景 Node.js 表现不好讲清楚优点也得讲清楚边界。Node.js 最大的软肋是 CPU 密集型任务。比如复杂的图片处理、超大文件压缩、重度计算类的算法如果直接在 Node 主线程里跑会把事件循环堵死导致整个服务“卡住”。因为单线程意味着同一个时刻只能执行一段代码你的同步计算占用了主线程后面排队的 I/O 回调全得等着。很多人黑 Node.js其实就是拿 CPU 密集型的场景去打它的短处。但这属于拿错工具还怪工具不好用。现实里的处理方案有很多用worker_threads把计算任务丢到子线程或者干脆把这种任务拆出去交给专门的 Go/Rust 服务。Node.js 做好它最擅长的 I/O 密集型工作就好架构上没有必要让它做所有事。2.4 前后端同一种语言这个优势到今天依然稀缺再聊一个常被忽略但极其重要的价值全栈语言统一。你用 TypeScript 定义了一套接口的类型这个类型可以同时被后端实现和前端调用直接复用你写后端的同事改字段名前端立刻就能在编译期发现错误。这在 Java 后端 JavaScript 前端的组合里是做不到的你得额外维护一坨 Schema、一份 API 文档或者用工具从 OpenAPI 生成类型。更实际的是团队问题。一个小团队想快速落地一个带后台管理的业务系统如果前后端技术栈都是 JS/TS那一个人可以从接口写到页面不用在两种语言之间来回切换心智。对于创业公司、外包项目、内部工具来说这个成本优势是实打实的钱和时间。3. 安装Node.js 20的正确姿势从LTS选择到Ubuntu实操聊完“为什么还在用”接下来上点实操。搜索框里高频出现的几个词——node.js lts下载、ubuntu安装node.js 20、node.js安装说明大多数人的第一个门槛其实是环境搭建。3.1 LTS、Current、奇数版本版本号背后到底有什么规则Node.js 的版本发布节奏是固定的偶数年份的 4 月发布一个偶数大版本比如 20、22、24这个版本会进入 LTS长期支持序列奇数年份的 10 月发布一个奇数大版本属于“尝鲜版”生命周期很短。拿 20、22、24 这三个大版本来说20 已经进入了维护期Maintenance LTS依然安全但新的特性不再往里加了22 是最典型的 Active LTS适合绝大多数生产环境24 是 2025 年 4 月发布的新版本也会走 LTS 流程适合想用新特性的项目。我的建议非常直接生产环境一律用带 LTS 标签的偶数版本个人学习可以跟 Current。不要在生产环境里碰奇数版本也不要盲目追最新的大版本至少等它发布几个月、社区把坑踩得差不多了再升。3.2 Ubuntu 上千万别直接用 apt 装 Node这是我要拍桌子强调的一件事。很多教程让你sudo apt install nodejs我严重不推荐。原因有三层第一Ubuntu 官方源里的 Node.js 版本非常滞后。比如 Ubuntu 22.04 自带的 Node.js 是 12.x 或者 18.x你装完一看版本大概率直接傻眼。第二apt 管理的 Node 和 npm 经常是分家的装出来的 npm 版本配套也可能对不上。第三将来你想切换 Node 版本、升级大版本用 apt 操作极其痛苦。在 Ubuntu 上我推荐两种方案nvmNode Version Manager或者 NodeSource 的 apt 源。如果你只需要一个固定版本、不想折腾NodeSource 是个好选择如果你想在多个 Node 版本之间自由切换比如今天测 20、明天测 22那 nvm 是最灵活的。我个人是 nvm 党因为前端项目五花八门经常要切版本。3.3 nvm 镜像源一套可以放心复制的安装流程下面是完整的 nvm 安装流程照着抄就行# 1. 安装 nvm curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash # 2. 重新加载配置文件 source ~/.bashrc # 3. 查看所有可以安装的 Node 版本 nvm ls-remote # 4. 安装 Node.js 20自动解析为当前最新的 20.x nvm install 20 # 5. 设置默认版本 nvm alias default 20 # 6. 验证 node -v npm -v如果你在服务器上拉取 Node.js 二进制比较慢可以给 nvm 配置镜像源本质上是换一个下载地址不影响任何功能export NVM_NODEJS_ORG_MIRRORhttps://npmmirror.com/mirrors/node装完 Node 之后顺手配置一下 npm 镜像源。这一步对于依赖比较大的项目来说能省掉大量等待时间。要不要用镜像源完全看你的网络环境如果用官方源不慢那保持默认也没问题npm config set registry https://registry.npmmirror.com装完之后顺手验证两个东西node -v是否输出了你期望的版本which node是否指向了 nvm 管理的路径。3.4 项目里的版本锁定光装好还不够很多人只在自己电脑上装好了 Node却忘了在项目层面锁定版本。等你把项目丢到 CI 或者另一台服务器上大概率会因为 Node 版本不一样而出现莫名其妙的构建错误。推荐做法是在项目根目录放一个.nvmrc文件里面只写一行20然后团队成员进入项目目录后执行nvm use就会自动切换到这个版本。再配合package.json里的engines字段做最终兜底{ engines: { node: 20 } }这三个动作做完你才算是真正把 Node.js 环境的坑堵住了。4. “ERROR installing 24.21.0”完整排查链路与版本发布规则最近很多人搜了一个报错error installing 24.21.0: node.js v24.21.0 is not yet released or is not ava...。这个问题很有代表性正好借它讲一条完整的排查思路。4.1 这个报错出现的典型场景这个报错通常出现在你执行nvm install 24.21.0、Dockerfile 里写了FROM node:24.21.0或者 CI 脚本里指定了某个具体的 Node 小版本号。字面意思很直白你想要的这个版本要么还没发布要么不存在。我第一次看到这报错时也愣了一下因为直觉上 Node.js 24 是存在的为什么装不了后来想明白了这里的问题是“24”和“24.21.0”完全是两个维度的信息。前者是大版本号后者是极其具体的完整版本号而完整版本号必须真实存在于官方发布列表里差一个 patch 版本都装不上。4.2 一步步排查先看真有没有这个版本遇到这种报错按下面的顺序来一般五分钟内能定位第一步先确认你想要的版本到底存不存在。最快的方式是直接查 Node.js 官方分发目录curl -s https://nodejs.org/dist/index.json | grep 24.21.0如果这里查不到那就死心吧这版本确实还没发布。还有一个更常用的办法nvm ls-remote | grep -E v?24\.这条命令会把所有远程可用的 24.x 版本列出来你一眼就能看到“24.21.0”到底在不在里面。第二步如果 nvm 列出来的远程列表明显滞后比如官方已经发了新版本但 nvm 里看不到那可能是 nvm 的版本索引没更新。升级 nvm 就能解决nvm upgrade第三步如果最近官方确实发布了 24.21.0但 nvm 还是装不了检查一下当前 nvm 版本是否太老。nvm 对 Node 新版本的支持偶尔会有滞后升级 nvm 之后通常能解决。4.3 这个报错背后的“版本号心态”问题实话说“24.21.0 is not yet released or is not available”这种报错最常见的成因根本不是环境问题而是版本号本身写错了。很多人喜欢在教程或者文档里看到一个具体版本号就照抄可那个版本号可能是虚构的、是以前某个 Python 版本号顺手填进去的、或者是没验证过的“预言未来”版本号。更合理的做法是永远不要手动指定一个你无法确认存在的具体小版本号。你在生产环境想要环境稳定就用 LTS 大版本号比如node:22不要写成node:22.14.0让系统解析到当前最新的 22.x你本地开发用 nvm 也一样直接nvm install 22它会自动解析成 22.x.y 里最新的那个。4.4 给生产环境加一道保险在 Docker 里固定大版本但又要保证可复现性有一个常见做法FROM node:22-alpine虽然写的是 22但镜像本身其实是被 digest哈希摘要锁定的。即使你写的是node:22同一时间拉下来的镜像内容也不会变。真正要小心的反而是本地开发环境因为nvm install 22会不断升级到最新的 22.x昨天还能跑的项目可能今天的小版本更新就带来了行为变化。应对方案很简单在package.json的engines里声明允许的版本范围在 CI 里用固定的镜像摘要在本地开发用.nvmrc锁定大版本。这套组合下来“过气”不好说但“跑不起来”的概率是真的小。5. 大厂和开源项目还在用Node的真实场景不止是写个API5.1 前端工程化这个世界上大部分前端工具链都跑在 Node 上先看一个我们每天都在用、但很容易忽略的部分前端工程化。Vite、Webpack、Rollup、Babel、ESLint、Prettier、PostCSS这些工具清一色是 Node.js 程序。你在 CI 上跑的npm run build、npm run test、npm run lint本质上都是在执行 Node.js 脚本。如果 Node.js 明天消失现代前端开发基本瘫痪。这不是夸张这是事实。你可以不用 React、不用 Vue但你很难不用到 npm 生态和基于 Node 构建的开发工具链。这也是为什么各大公司在前端基建方面投入再大也绕不开 Node.js——它已经是前端工程化的基础设施了。5.2 SSR 与全栈框架Next.js、Nuxt 背后的运行时全栈框架是这两年最火的话题之一Next.js 几乎成了 React 项目的默认选择。但很多人没意识到Next.js 的服务端渲染、静态生成、API 路由这些能力全部跑在 Node.js 运行时之上。Nuxt、SvelteKit、Astro 也一样它们的 SSR 能力和 Node.js 深度绑定。这些框架之所以流行恰恰是因为 Node.js 提供了一个足够成熟的服务器端环境进程管理器、日志、热更新、调试工具、文件系统访问、流式响应该有的都有。与其说 Node.js 过气了不如说它换了一种形态藏在了所有全栈框架的底层。5.3 BFF 层前端团队自己说了算的中间层再说一个 Node.js 的主场BFFBackend For Frontend。很多中大型公司的架构里前端团队不希望页面直接调到后端复杂的业务接口于是中间加一层 Node.js BFF负责聚合数据、适配接口、做一些轻量的权限判断和逻辑编排。这种场景对“开发效率”和“团队自治”的要求远高于对“极致性能”的要求。前端同学用自己最熟悉的 TypeScript 写一个中间层不用求着 Java 后端改接口也不需要在页面里处理一堆拼装逻辑。Node.js 在这个位置几乎是唯一合理的选择——你总不能让前端团队为了一个中间层去学 Go 或者 Java。5.4 Serverless 各类函数计算云函数FaaS是过去几年非常重要的后端形态而 Node.js 是各大云厂商对函数计算运行时支持最完善的语言没有之一。Node 函数冷启动快、内存占用小、生态丰富配合 TypeScript 写起来很舒服。在高并发场景下平台上每秒可以拉起成千上万个 Node 实例成本控制也很乐观。很多团队的整个业务逻辑都跑在函数计算上平时根本感觉不到 Node.js 的存在。但它恰恰是函数计算平台上运行数量最多的运行时之一。5.5 命令行工具与桌面应用最后说两个大家都见过的场景。Electron 桌面应用、Visual Studio Code 插件体系全部围绕 Node.js 生态。VS Code 的插件本质上就是一个 Node.js 程序。我们团队内部的一堆 CLI 工具比如代码生成器、Schema 同步脚本、数据迁移工具也都是 Node.js 写的一个文件丢过去就能跑换机器成本为零。写 CLI 工具这件事Node.js 有着近乎统治性的优势生态里有commander、inquirer、chalk、execa这类极其成熟的小工具库拼装起来速度快到让人上瘾。6. Deno和Bun虎视眈眈为什么多数团队仍把Node当默认运行时6.1 新运行时到底快在哪适合用在哪再回过头来看 Deno 和 Bun。Deno 最显著的特点是原生 TypeScript 支持和安全权限模型脚本需要显式授权才能访问网络或文件系统Bun 则主打性能内置打包器、测试器、安装器bun install的速度可以比 npm 快几倍甚至几十倍启动速度也远优于 Node。在新的个人项目里尝试这些运行时体验确实相当惊艳。我见过有人用 Bun 做项目的构建脚本几十个依赖的安装时间从两三分钟压到十几秒感受只能用“丝滑”来形容。Deno 在写内部管理脚本、定时任务类工具时原生 TypeScript 自带依赖缓存也很省心。6.2 但为什么生产环境还是选 Node因为选运行时从来不是在比较单一维度的“快”而是在评估一个组合生态、稳定性、人才储备、运维经验、云厂商支持。Node.js 在这几个维度上的综合分目前没有任何一个运行时能超越。生产环境第一条是稳定。你踩过的坑几乎都能在 Node.js 生态里找到答案你在 npm 上要找的包十年前就已经有人写好并长期维护了。而新运行时哪怕再快一旦遇到社区里没人遇到过的边缘问题就只能自己啃。云厂商的 Function 运行时对 Node 的支持最成熟各种 APM、日志、告警生态也都完美适配。这些都是隐性的“迁移成本”。6.3 我的选择标准不追新不守旧按场景干活说了这么多我并不是建议你别碰新运行时。我的实际倾向是分开看个人学习、小工具、内部脚本大胆用 Deno 或 Bun体验新特性的同时长见识新项目的后端 API如果团队没人用过新运行时我依然选 Node.js或直接上成熟框架需要极致冷启动的 ServerlessNode.js 依然是一个非常优秀的选择前端构建工具链跟着框架生态走但运行环境基本还是 Node说到底Node.js 是不是“过气”取决于你如何定义过气。如果过气等于“不再是热搜第一的技术”那它确实过气了。但如果过气等于“没有人实际使用、没有生产力价值”那它离过气还远得很。6.4 生态才是最深的护城河我见过太多技术争论Deno 比 Node 安全、Bun 比 Node 快、Rust 和 Go 比 Node 性能好。这些说法各自有各自的道理但落到“今天上线一个系统”的选择时生态深度才是决定性因素。npm 生态今天依然是几十亿次的周下载量几乎任何你想做的功能都能找到一个经过线上环境验证的包。这种积累不是靠“快”就能追上的。Node.js 真正的护城河不在于 V8 引擎本身有多快而在于过去十几年里全世界开发者在这套生态里投入的代码、踩过的坑、沉淀下的工具。我个人在实际维护中的体会是那些高喊“Node.js 已死”的人通常并不需要维护一个跑了两三年的线上服务。当你凌晨两点被告警吵醒用一个node --inspect加 Chrome DevTools 排查线上内存泄漏的时候当你的团队新人半天之内就能上手维护你的 Node 服务并且不闯祸的时候你才会明白稳定意味着什么。最后再分享一个小技巧如果你在线上遇到可疑的 Node 进程异常不要急着重启先执行node --trace-warnings或者抓一份.heapsnapshot堆快照下来用chrome://inspect分析一遍很多时候问题原因一目了然——这套流程我在 Node 生态里用了十年都不腻。
阅读完成 · 觉得有帮助?