跳转到主内容
返回博客列表

Node.js 大变天:26 转 LTS、一年一版时代开启,node 直接跑 TypeScript,但升级有坑

前言

“我们什么都没改,早上一开电脑 CI 全红了。”

10 月 28 日之后,不少团队陆续踩中同一个坑:Dockerfile 里钉着浮动 node:lts 标签,Node 26 接棒 LTS 当天,构建环境一夜从 24 跳到 26,原生插件编译不过、老 API 直接报错。

这不是偶然,而是两件事撞在了一起:Node 26 接棒 LTS,以及 Node.js 十年来最大的一次发布规则改版。

今天这篇文章,我把这次大版本更新彻底讲透:到底发生了什么、新特性怎么用、升级前必须避开哪些坑。文中所有关键事实都经过官方信源逐一核实,可以直接抄作业。


一、到底发生了什么

1. Node 26 接棒 LTS

先看现役版本格局(截至 2026-11-14):

版本代号状态关键节点
26.xLithiumActive LTS2026-05-05 发布 v26.0.0;2026-10-28 转 LTS;EOL 2029-04-30
24.xKryptonMaintenance2026-10-20 进入维护期;EOL 2028-04-30
22.xJodMaintenanceEOL 2027-04-30
27.x—Alpha2026-10-28 起预发布;计划 2027-04-22 正式发布

Node 26(代号 Lithium)在 2026-10-28 发布 v26.13.0 正式进入 Active LTS,最新版 v26.13.1(2026-11-10,内置 npm 11.20.0)。同时 Node 24 进入维护期,只修安全 bug 不加新特性了。

2. 十年奇偶双轨制,终结

更大的新闻是官方同日落地的发布节奏改版,公告原文说得直白:自 27 起,从半年一个大版本改为一年一个。

新节奏是这样转的:

  • 每年 10 月:从 main 切出新版本线,先做 6 个月 Alpha(允许破坏性变更)
  • 次年 4 月:发布 x.0.0 进入 Current
  • 当年 10 月:转入 LTS,支持到第三年 4 月

也就是说,每个大版本都会转 LTS——过去”奇数版尝鲜、偶数版求稳”的十年老规矩作废了。官方给的理由也很实在:奇数版本采用率极低,四五条活跃线同时做安全维护,扛不住。

官方公告地址: https://nodejs.org/en/blog/announcements/evolving-the-nodejs-release-schedule

3. 一个魔幻的现状:历史上第一次没有 Current

按旧节奏,Node 27 本该在 10 月下旬发布为 Current。但这次你去 nodejs.org 首页看,只有两个下载标签:Latest LTS(v26.13.1)和 Latest Alpha。

Node 27 目前只有两个 Alpha 预发布(最新 v27.0.0-alpha.0.1.0,已内置 npm 12.x),正式版要等到 2027-04-22。当下不存在任何处于 Current 阶段的版本——这是改制过渡期的特殊现象,看到”Node 27 已发布”的说法一律是错的。


二、最值得上手的新特性

以下代码全部在 v26.13.1 官方二进制上实测通过,零 flag。

1. node 直接跑 TypeScript,彻底转正

这是 Node 26 最出圈的特性。演进路线走了两年:

  • v22.6.0:--experimental-strip-types 实验引入
  • v23.6.0:默认开启
  • v25.2.0 / v24.12.0:标记 Stable
  • v26.0.0:连 --experimental-transform-types 都移除了,只保留稳定的类型剥离
// app.ts —— Node 26 直接运行:node app.ts
interface User { id: number; name: string }
const u: User = { id: 1, name: 'fish' };
console.log(process.features.typescript); // → "strip"

注意它做的是类型剥离(strip),不是编译。所以 enum、带运行时代码的 namespace、参数属性这类需要代码生成的语法会直接抛 ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX——官方的迁移建议是用 tsx 这类第三方加载器。

2. Temporal 日期时间 API 默认启用

被吐槽了十几年的 Date,终于有官方继任者了。v26 起 Temporal 全局默认可用:

new Temporal.PlainDate(2026, 11, 14).toString(); // → "2026-11-14"
Temporal.Now.plainDateISO().toString();          // → 今天

时区、日历、不可变对象、精确到纳秒,都是 Date 的痛点。社区好评归好评,两个槽点也很统一:和 Temporal.io 的工作流 SDK 撞了名字;Safari 是唯一还没支持的浏览器,全端使用还差一口气。

3. Permission Model 转正,还多了个审计模式

--permission 沙箱不再是实验特性,权限覆盖 fs、net、child-process、worker、addons、wasi、ffi、openssl-store 八类。

更实用的是 v25.8.0 新增的审计模式:只上报不拦截,先摸清你的应用到底要哪些权限,再收紧:

# 第一步:审计模式,只记录不拦截
node --permission-audit app.js
# 控制台会输出类似:{ "permission": "FileSystemRead", "resource": "target.txt" }

# 第二步:按审计结果收紧
node --permission --allow-fs-read=./ app.js
# 越权访问直接抛 ERR_ACCESS_DENIED

4. V8 升到 14.6,新语法开箱即用

Node 26 内置 V8 14.6.202(对应 Chromium 146),几个新语法默认可用:

const m = new Map([['a', 1]]);
m.getOrInsert('b', 42);              // → 42,Upsert 提案
Iterator.concat([1], [2]).toArray(); // → [1, 2]

另外 node:sqlite 升到 Release Candidate(Stability 1.2),无需任何 flag:

const { DatabaseSync } = require('node:sqlite');
const db = new DatabaseSync(':memory:');
db.exec('CREATE TABLE t(v TEXT)');
db.prepare('INSERT INTO t VALUES (?)').run('hi');
console.log(db.prepare('SELECT v FROM t').get()); // → { v: 'hi' }

小工具们也都稳了:node:test 测试运行器 Stable、--watch 稳定、Undici 升到 8.x。


三、升级前必须知道的坑

1. 原生插件 ABI 从 137 跳到 147

V8 大版本升级导致 NODE_MODULE_VERSION 从 137 跳到 147。所有用 NODE_MODULE 宏直接对接 V8 的原生 C++ 插件,在 Node 26 下 require 直接报错,必须重编译。

好消息:走 Node-API 的插件实测不受影响,这也是现在写原生插件的正确姿势。自查一行命令:

node -p "process.versions.modules"   # Node 24 → 137,Node 26 → 147

社区还有人提醒:原生插件的预编译适配通常滞后 LTS 标签几周,别在接棒当天就冲。

2. —experimental-transform-types 整个没了

v26 执行这个 flag 直接 bad option。如果你的项目靠它跑 enum 这类需要代码生成的 TS 语法,升级就挂。方案很明确:换 tsx。

3. 一批 API 硬移除,GCM 短标签直接抛错

  • http.ServerResponse.prototype.writeHeader()(少个 d 的那个老 API)已移除,改用 writeHead()
  • 全部 _stream_* 内部流模块报 ERR_UNKNOWN_BUILTIN_MODULE
  • GCM 加密注意:DEP0182 转 End-of-Life,setAuthTag() 不再接受短于 16 字节的认证标签,除非显式声明:
const { createDecipheriv } = require('node:crypto');
// 修复:短标签必须显式传 authTagLength
const d = createDecipheriv('aes-256-gcm', key, iv, { authTagLength: 8 });
  • corepack 不再随 Node 出货,pnpm/yarn 要自己装了——这是 HN 上情绪最强烈的不满
  • type: "module" 包里 require() 无扩展名文件的旧例外取消,按 ESM 解析,依赖旧写法的包(如 yargs v17)会响亮报错

📌 Docker 用户重点:把 FROM node:lts 改成钉精确版本 FROM node:26.13.1,再用 Renovate/Dependabot 走 PR 升级——LTS 接棒当天的翻车帖,几乎全是浮动标签惹的祸。


四、社区吵什么

性能叙事是分裂的。一份开源可复现的社区基准(对比 24.15.0 / 25.9.0 / 26.2.0)显示:合成真实应用里 Node 26 双优,p95 延迟 1.65ms 三者最低、峰值内存 273MB 也最低;但定向微基准有输面——HTTP GET 吞吐比 24 低约 7%,字符串拼接跌 32%;而整数循环快了约 9.5 倍,这是 V8 升级的红利。

Bun 在后面猛追。Bun 1.4 直接拿 Node v26.3.0 官方测试套件对表,新增 1517 项通过,自测数据里启动速度 5.1ms vs 27.2ms、安装依赖 1.41s vs 18.1s——当然对比口径是 Bun 自己定的,看个热闹。

生态跟进很快:Vercel 已把 26.x 设为新项目默认运行时;Vite 8 和 Next.js 16 的最低要求都还停在 Node 20/22,不升 26 也能用。

基本盘还在涨:2026 年前 7 个月 Node.js 下载量 46.1 亿次,已超 2025 全年。


总结

这次大版本更新,一句话概括:Node 26 接棒 LTS,同时 Node.js 进入一年一版的新纪元。

给你的行动清单:

  1. 生产环境:钉精确版本号,别用浮动 node:lts 标签
  2. 升级 Node 26 前:跑一遍 process.versions.modules 自查原生插件,GCM 短标签代码先改
  3. 本地开发:现在就装 Node 26,node app.ts 直接跑 TypeScript 的体验值得立刻上手
  4. 明年 4 月 22 日:Node 27.0.0 正式发布,那就是一年一版新节奏的第一个成品

版本规则改了,但方向是好的——更少的维护线、更长的支持期、更稳定的预期。这波不亏。

欢迎关注公众号 FishTech Notes,一块交流使用心得!